/*
 * Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Christian W. Damus (CEA LIST) - initial API and implementation
 */
package org.eclipse.emf.cdo.security.internal.ui.editor;

import static org.eclipse.emf.cdo.security.internal.ui.util.SecurityUIUtil.getTypeFilter;
import static org.eclipse.emf.cdo.security.internal.ui.util.SecurityUIUtil.getViewerFilter;

import org.eclipse.emf.cdo.eresource.CDOResourceNode;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.security.Access;
import org.eclipse.emf.cdo.security.FilterPermission;
import org.eclipse.emf.cdo.security.PatternStyle;
import org.eclipse.emf.cdo.security.ResourceFilter;
import org.eclipse.emf.cdo.security.Role;
import org.eclipse.emf.cdo.security.SecurityFactory;
import org.eclipse.emf.cdo.security.SecurityPackage;
import org.eclipse.emf.cdo.security.internal.ui.dialogs.FilterTreeSelectionDialog;
import org.eclipse.emf.cdo.security.internal.ui.messages.Messages;
import org.eclipse.emf.cdo.security.internal.ui.util.EditableDialogCellEditor;
import org.eclipse.emf.cdo.security.internal.ui.util.INewObjectConfigurator;
import org.eclipse.emf.cdo.security.internal.ui.util.OneToManyTableBlock;
import org.eclipse.emf.cdo.security.internal.ui.util.ResourceBasedPermissionFilter;
import org.eclipse.emf.cdo.security.provider.SecurityEditPlugin;
import org.eclipse.emf.cdo.ui.CDOItemProvider;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.container.IContainer;

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ComboBoxViewerCellEditor;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.forms.widgets.FormToolkit;

import java.util.Collections;

/**
 * The details page for {@link Role} master selections.  Includes a table
 * that provides in-line editing of resource-based permissions.
 *
 * @author Christian W. Damus (CEA LIST)
 */
public class RoleDetailsPage extends AbstractDetailsPage<Role>
{
  public RoleDetailsPage(EditingDomain domain, AdapterFactory adapterFactory)
  {
    super(Role.class, SecurityPackage.Literals.ROLE, domain, adapterFactory);
  }

  @Override
  protected void createContents(Composite parent, FormToolkit toolkit)
  {
    super.createContents(parent, toolkit);

    text(parent, toolkit, Messages.RoleDetailsPage_0, SecurityPackage.Literals.ROLE__ID);

    space(parent, toolkit);

    OneToManyTableBlock perms = table(parent, toolkit, Messages.RoleDetailsPage_1, createTableConfiguration());
    perms.setNewObjectConfigurator(createNewPermissionConfigurator());

    space(parent, toolkit);

    oneToMany(parent, toolkit, Messages.RoleDetailsPage_2, SecurityPackage.Literals.ROLE__ASSIGNEES,
        SecurityPackage.Literals.GROUP);

    oneToMany(parent, toolkit, Messages.RoleDetailsPage_3, SecurityPackage.Literals.ROLE__ASSIGNEES,
        SecurityPackage.Literals.USER);
  }

  protected INewObjectConfigurator createNewPermissionConfigurator()
  {
    return new INewObjectConfigurator()
    {

      public Command createConfigureCommand(Object newObject)
      {
        ResourceFilter filter = SecurityFactory.eINSTANCE.createResourceFilter("/home/${user}", PatternStyle.TREE); //$NON-NLS-1$
        Command result = CreateChildCommand.create(getEditingDomain(), newObject, new CommandParameter(newObject,
            SecurityPackage.Literals.FILTER_PERMISSION__FILTERS, filter), Collections.singleton(newObject));
        result = result.chain(SetCommand.create(getEditingDomain(), newObject,
            SecurityPackage.Literals.PERMISSION__ACCESS, Access.WRITE));
        return result;
      }
    };
  }

  protected OneToManyTableBlock.ITableConfiguration createTableConfiguration()
  {
    return new OneToManyTableBlock.TableConfiguration(SecurityPackage.Literals.ROLE__PERMISSIONS,
        SecurityPackage.Literals.FILTER_PERMISSION, new ResourceBasedPermissionFilter())
    {
      private static final int COL_ACCESS = 0;

      private static final int COL_PATTERN_STYLE = 1;

      private static final int COL_PATH = 2;

      private final String[] columnTitles = { Messages.RoleDetailsPage_5, Messages.RoleDetailsPage_6,
          Messages.RoleDetailsPage_7 };

      private final CellEditor[] cellEditors = new CellEditor[3];

      public String[] getColumnTitles()
      {
        return columnTitles;
      }

      public int getColumnWeight(int index)
      {
        switch (index)
        {
        case COL_ACCESS:
          return 15;
        case COL_PATTERN_STYLE:
          return 15;
        case COL_PATH:
          return 70;
        default:
          throw new IllegalArgumentException("index"); //$NON-NLS-1$
        }
      }

      public int getColumnMinimumSize(int index)
      {
        switch (index)
        {
        case COL_ACCESS:
          return 30;
        case COL_PATTERN_STYLE:
          return 30;
        case COL_PATH:
          return 120;
        default:
          throw new IllegalArgumentException("index"); //$NON-NLS-1$
        }
      }

      public boolean isColumnResizable(int index)
      {
        switch (index)
        {
        case COL_ACCESS:
          return false;
        case COL_PATTERN_STYLE:
          return false;
        case COL_PATH:
          return true;
        default:
          throw new IllegalArgumentException("index"); //$NON-NLS-1$
        }
      }

      public CellLabelProvider getLabelProvider(TableViewer viewer, final int columnIndex)
      {
        return new ColumnLabelProvider()
        {
          @Override
          public String getText(Object element)
          {
            final FilterPermission perm = (FilterPermission)element;
            final ResourceFilter filter = perm.getFilters().isEmpty() ? null : (ResourceFilter)perm.getFilters().get(0);

            switch (columnIndex)
            {
            case COL_ACCESS:
              return SecurityEditPlugin.INSTANCE.getString(String.format("_UI_Access_%s_literal", perm.getAccess())); //$NON-NLS-1$
            case COL_PATTERN_STYLE:
            {
              String result = "=="; //$NON-NLS-1$
              if (filter != null && filter.getPatternStyle() != null)
              {
                switch (filter.getPatternStyle())
                {
                case EXACT:
                  break;
                case TREE:
                  result = ">="; //$NON-NLS-1$
                  break;
                default:
                  result = "~="; //$NON-NLS-1$
                  break;
                }
              }
              return result;
            }
            case COL_PATH:
              return filter == null ? "" : filter.getPath(); //$NON-NLS-1$
            default:
              throw new IllegalArgumentException("columnIndex"); //$NON-NLS-1$
            }
          }
        };
      }

      public boolean canEdit(TableViewer viewer, Object element, int columnIndex)
      {
        return true;
      }

      public void setValue(TableViewer viewer, Object element, int columnIndex, Object value)
      {
        final FilterPermission perm = (FilterPermission)element;
        final ResourceFilter filter = (ResourceFilter)perm.getFilters().get(0);

        switch (columnIndex)
        {
        case COL_ACCESS:
          if (perm.getAccess() != value)
          {
            execute(SetCommand.create(getEditingDomain(), perm, SecurityPackage.Literals.PERMISSION__ACCESS, value));
            viewer.refresh(element);
          }
          break;
        case COL_PATTERN_STYLE:
          if (filter.getPatternStyle() != value)
          {
            execute(SetCommand.create(getEditingDomain(), filter,
                SecurityPackage.Literals.RESOURCE_FILTER__PATTERN_STYLE, value));
            viewer.refresh(element);
          }
          break;
        case COL_PATH:
          if (!ObjectUtil.equals(filter.getPath(), value))
          {
            execute(SetCommand
                .create(getEditingDomain(), filter, SecurityPackage.Literals.RESOURCE_FILTER__PATH, value));
            viewer.refresh(element);
          }
          break;
        default:
          throw new IllegalArgumentException("columnIndex"); //$NON-NLS-1$
        }
      }

      public Object getValue(TableViewer viewer, Object element, int columnIndex)
      {
        final FilterPermission perm = (FilterPermission)element;
        final ResourceFilter filter = (ResourceFilter)perm.getFilters().get(0);

        switch (columnIndex)
        {
        case COL_ACCESS:
          return perm.getAccess();
        case COL_PATTERN_STYLE:
          return filter.getPatternStyle();
        case COL_PATH:
          return filter.getPath();
        default:
          throw new IllegalArgumentException("columnIndex"); //$NON-NLS-1$
        }
      }

      public CellEditor getCellEditor(final TableViewer viewer, int columnIndex)
      {
        CellEditor result = cellEditors[columnIndex];
        if (result == null)
        {
          result = createCellEditor(viewer, columnIndex);
          cellEditors[columnIndex] = result;
        }

        return result;
      }

      protected CellEditor createCellEditor(TableViewer viewer, int columnIndex)
      {
        Composite parent = (Composite)viewer.getControl();

        switch (columnIndex)
        {
        case COL_ACCESS:
        {
          ComboBoxViewerCellEditor result = new ComboBoxViewerCellEditor(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
          result.setLabelProvider(new AdapterFactoryLabelProvider(getAdapterFactory()));
          result.setContentProvider(new ArrayContentProvider());
          result.setInput(Access.VALUES);
          return result;
        }
        case COL_PATTERN_STYLE:
        {
          ComboBoxViewerCellEditor result = new ComboBoxViewerCellEditor(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
          result.setLabelProvider(new AdapterFactoryLabelProvider(getAdapterFactory()));
          result.setContentProvider(new ArrayContentProvider());
          result.setInput(PatternStyle.VALUES);
          return result;
        }
        case COL_PATH:
          return new EditableDialogCellEditor(parent)
          {

            @Override
            protected Object openDialogBox(Control cellEditorWindow)
            {
              final CDOView view = getInput().cdoView();
              @SuppressWarnings({ "rawtypes", "unchecked" })
              CDOItemProvider provider = new CDOItemProvider(null)
              {
                private boolean connected;

                {
                  // Connect the input now, because the dialog will try to access the content provider before it has
                  // been set into the tree viewer
                  connectInput((IContainer)view);
                }

                @Override
                protected void connectInput(IContainer<Object> input)
                {
                  if (!connected)
                  {
                    super.connectInput(input);
                    connected = true;
                  }
                }

                @Override
                protected void disconnectInput(IContainer<Object> input)
                {
                  if (connected)
                  {
                    connected = false;
                    super.disconnectInput(input);
                  }
                }
              };

              FilterTreeSelectionDialog dlg = new FilterTreeSelectionDialog(cellEditorWindow.getShell(), provider,
                  provider);

              dlg.setAllowMultiple(false);
              dlg.setMessage(Messages.RoleDetailsPage_4);
              dlg.setTitle(Messages.RoleDetailsPage_8);
              dlg.setDoubleClickSelects(true);
              dlg.addFilter(getViewerFilter(getTypeFilter(EresourcePackage.Literals.CDO_RESOURCE_NODE)));
              dlg.setBlockOnOpen(true);

              String current = (String)getValue();

              dlg.setInput(view);
              if (current != null && view.hasResource(current))
              {
                dlg.setInitialSelection(view.getResourceNode(current));
              }

              String result = null;

              if (dlg.open() == Window.OK)
              {
                CDOResourceNode node = (CDOResourceNode)dlg.getFirstResult();
                if (node != null)
                {
                  result = node.getPath();
                }
              }

              return result;
            }
          };
        default:
          throw new IllegalArgumentException("columnIndex"); //$NON-NLS-1$
        }
      }
    };
  }
}
