// 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.ErrorDialog;
import com.google.gerrit.client.Gerrit;
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.GroupInfo;
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.AccountGroup;
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;
import java.util.Map;

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 Map<AccountGroup.UUID, GroupInfo> groupInfo;
  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.groupInfo = projectAccess.getGroupInfo();
    this.labelTypes = labelTypes;

    PermissionNameRenderer nameRenderer =
        new PermissionNameRenderer(projectAccess.getCapabilities());
    normalName = new ValueLabel<>(nameRenderer);
    deletedName = new ValueLabel<>(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(@SuppressWarnings("unused") MouseOverEvent event) {
    addStyleName(AdminResources.I.css().deleteSectionHover());
  }

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

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

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

  @UiHandler("beginAddRule")
  void onBeginAddRule(@SuppressWarnings("unused") 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(@SuppressWarnings("unused") 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(
      @SuppressWarnings("unused") CloseEvent<GroupReferenceBox> event) {
    hideAddGroup();
  }

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

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

  private void addGroup(final 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);
                new ErrorDialog(Gerrit.M.noSuchGroupMessage(ref.getName()))
                    .center();
              }
            }

            @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<>(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, groupInfo, 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);
    }
  }
}
