// Copyright (C) 2011 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.client.admin;

import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.ui.SuggestUtil;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.ProjectAccess;
import com.google.gerrit.common.data.RefConfigSection;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.editor.client.Editor;
import com.google.gwt.editor.client.EditorDelegate;
import com.google.gwt.editor.client.ValueAwareEditor;
import com.google.gwt.editor.client.adapters.EditorSource;
import com.google.gwt.editor.client.adapters.ListEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.ValueLabel;

import java.util.ArrayList;
import java.util.List;

public class PermissionEditor extends Composite implements Editor<Permission>,
    ValueAwareEditor<Permission> {
  interface Binder extends UiBinder<HTMLPanel, PermissionEditor> {
  }

  private static final Binder uiBinder = GWT.create(Binder.class);

  @UiField(provided = true)
  @Path("name")
  ValueLabel<String> normalName;

  @UiField(provided = true)
  @Path("name")
  ValueLabel<String> deletedName;

  @UiField
  CheckBox exclusiveGroup;

  @UiField
  FlowPanel ruleContainer;
  ListEditor<PermissionRule, PermissionRuleEditor> rules;

  @UiField
  DivElement addContainer;
  @UiField
  DivElement addStage1;
  @UiField
  DivElement addStage2;
  @UiField
  Anchor beginAddRule;
  @UiField
  @Editor.Ignore
  GroupReferenceBox groupToAdd;
  @UiField
  Button addRule;

  @UiField
  Anchor deletePermission;

  @UiField
  DivElement normal;
  @UiField
  DivElement deleted;

  private final Project.NameKey projectName;
  private final boolean readOnly;
  private final AccessSection section;
  private final LabelTypes labelTypes;
  private Permission value;
  private PermissionRange.WithDefaults validRange;
  private boolean isDeleted;

  public PermissionEditor(ProjectAccess projectAccess,
      boolean readOnly,
      AccessSection section,
      LabelTypes labelTypes) {
    this.readOnly = readOnly;
    this.section = section;
    this.projectName = projectAccess.getProjectName();
    this.labelTypes = labelTypes;

    PermissionNameRenderer nameRenderer =
        new PermissionNameRenderer(projectAccess.getCapabilities());
    normalName = new ValueLabel<String>(nameRenderer);
    deletedName = new ValueLabel<String>(nameRenderer);

    initWidget(uiBinder.createAndBindUi(this));
    groupToAdd.setProject(projectName);
    rules = ListEditor.of(new RuleEditorSource());

    exclusiveGroup.setEnabled(!readOnly);
    exclusiveGroup.setVisible(RefConfigSection
        .isValid(section.getName()));

    if (readOnly) {
      addContainer.removeFromParent();
      addContainer = null;

      deletePermission.removeFromParent();
      deletePermission = null;
    }
  }

  @UiHandler("deletePermission")
  void onDeleteHover(MouseOverEvent event) {
    addStyleName(AdminResources.I.css().deleteSectionHover());
  }

  @UiHandler("deletePermission")
  void onDeleteNonHover(MouseOutEvent event) {
    removeStyleName(AdminResources.I.css().deleteSectionHover());
  }

  @UiHandler("deletePermission")
  void onDeletePermission(ClickEvent event) {
    isDeleted = true;
    normal.getStyle().setDisplay(Display.NONE);
    deleted.getStyle().setDisplay(Display.BLOCK);
  }

  @UiHandler("undoDelete")
  void onUndoDelete(ClickEvent event) {
    isDeleted = false;
    deleted.getStyle().setDisplay(Display.NONE);
    normal.getStyle().setDisplay(Display.BLOCK);
  }

  @UiHandler("beginAddRule")
  void onBeginAddRule(ClickEvent event) {
    beginAddRule();
  }

  void beginAddRule() {
    addStage1.getStyle().setDisplay(Display.NONE);
    addStage2.getStyle().setDisplay(Display.BLOCK);

    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
      @Override
      public void execute() {
        groupToAdd.setFocus(true);
      }
    });
  }

  @UiHandler("addRule")
  void onAddGroupByClick(ClickEvent event) {
    GroupReference ref = groupToAdd.getValue();
    if (ref != null) {
      addGroup(ref);
    } else {
      groupToAdd.setFocus(true);
    }
  }

  @UiHandler("groupToAdd")
  void onAddGroupByEnter(SelectionEvent<GroupReference> event) {
    GroupReference ref = event.getSelectedItem();
    if (ref != null) {
      addGroup(ref);
    }
  }

  @UiHandler("groupToAdd")
  void onAbortAddGroup(CloseEvent<GroupReferenceBox> event) {
    hideAddGroup();
  }

  @UiHandler("hideAddGroup")
  void hideAddGroup(ClickEvent event) {
    hideAddGroup();
  }

  private void hideAddGroup() {
    addStage1.getStyle().setDisplay(Display.BLOCK);
    addStage2.getStyle().setDisplay(Display.NONE);
  }

  private void addGroup(GroupReference ref) {
    if (ref.getUUID() != null) {
      if (value.getRule(ref) == null) {
        PermissionRule newRule = value.getRule(ref, true);
        if (validRange != null) {
          int min = validRange.getDefaultMin();
          int max = validRange.getDefaultMax();
          newRule.setRange(min, max);

        } else if (GlobalCapability.PRIORITY.equals(value.getName())) {
          newRule.setAction(PermissionRule.Action.BATCH);
        }

        rules.getList().add(newRule);
      }
      groupToAdd.setValue(null);
      groupToAdd.setFocus(true);

    } else {
      // If the oracle didn't get to complete a UUID, resolve it now.
      //
      addRule.setEnabled(false);
      SuggestUtil.SVC.suggestAccountGroupForProject(
          projectName, ref.getName(), 1,
          new GerritCallback<List<GroupReference>>() {
            @Override
            public void onSuccess(List<GroupReference> result) {
              addRule.setEnabled(true);
              if (result.size() == 1) {
                addGroup(result.get(0));
              } else {
                groupToAdd.setFocus(true);
              }
            }

            @Override
            public void onFailure(Throwable caught) {
              addRule.setEnabled(true);
              super.onFailure(caught);
            }
          });
    }
  }

  boolean isDeleted() {
    return isDeleted;
  }

  @Override
  public void setValue(Permission value) {
    this.value = value;

    if (Permission.hasRange(value.getName())) {
      LabelType lt = labelTypes.byLabel(value.getLabel());
      if (lt != null) {
        validRange = new PermissionRange.WithDefaults(
            value.getName(),
            lt.getMin().getValue(), lt.getMax().getValue(),
            lt.getMin().getValue(), lt.getMax().getValue());
      }
    } else if (GlobalCapability.isCapability(value.getName())) {
      validRange = GlobalCapability.getRange(value.getName());

    } else {
      validRange = null;
    }

    if (Permission.OWNER.equals(value.getName())) {
      exclusiveGroup.setEnabled(false);
    } else {
      exclusiveGroup.setEnabled(!readOnly);
    }
  }

  @Override
  public void flush() {
    List<PermissionRule> src = rules.getList();
    List<PermissionRule> keep = new ArrayList<PermissionRule>(src.size());

    for (int i = 0; i < src.size(); i++) {
      PermissionRuleEditor e =
          (PermissionRuleEditor) ruleContainer.getWidget(i);
      if (!e.isDeleted()) {
        keep.add(src.get(i));
      }
    }
    value.setRules(keep);
  }

  @Override
  public void onPropertyChange(String... paths) {
  }

  @Override
  public void setDelegate(EditorDelegate<Permission> delegate) {
  }

  private class RuleEditorSource extends EditorSource<PermissionRuleEditor> {
    @Override
    public PermissionRuleEditor create(int index) {
      PermissionRuleEditor subEditor =
          new PermissionRuleEditor(readOnly, section, value, validRange);
      ruleContainer.insert(subEditor, index);
      return subEditor;
    }

    @Override
    public void dispose(PermissionRuleEditor subEditor) {
      subEditor.removeFromParent();
    }

    @Override
    public void setIndex(PermissionRuleEditor subEditor, int index) {
      ruleContainer.insert(subEditor, index);
    }
  }
}
