// Copyright (C) 2008 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.Gerrit;
import com.google.gerrit.client.GerritUiExtensionPoint;
import com.google.gerrit.client.StringListPanel;
import com.google.gerrit.client.access.AccessMap;
import com.google.gerrit.client.access.ProjectAccessInfo;
import com.google.gerrit.client.actions.ActionButton;
import com.google.gerrit.client.api.ExtensionPanel;
import com.google.gerrit.client.change.Resources;
import com.google.gerrit.client.download.DownloadPanel;
import com.google.gerrit.client.info.ActionInfo;
import com.google.gerrit.client.info.DownloadInfo.DownloadCommandInfo;
import com.google.gerrit.client.info.DownloadInfo.DownloadSchemeInfo;
import com.google.gerrit.client.projects.ConfigInfo;
import com.google.gerrit.client.projects.ConfigInfo.ConfigParameterInfo;
import com.google.gerrit.client.projects.ConfigInfo.ConfigParameterValue;
import com.google.gerrit.client.projects.ConfigInfo.InheritedBooleanInfo;
import com.google.gerrit.client.projects.ProjectApi;
import com.google.gerrit.client.rpc.CallbackGroup;
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.NativeMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.NpIntTextBox;
import com.google.gerrit.client.ui.OnEditEnabler;
import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ProjectState;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasEnabled;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.globalkey.client.NpTextArea;
import com.google.gwtexpui.globalkey.client.NpTextBox;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class ProjectInfoScreen extends ProjectScreen {
  private boolean isOwner;
  private boolean configVisible;

  private LabeledWidgetsGrid grid;
  private Panel pluginOptionsPanel;
  private LabeledWidgetsGrid actionsGrid;

  // Section: Project Options
  private ListBox requireChangeID;
  private ListBox submitType;
  private ListBox state;
  private ListBox contentMerge;
  private ListBox newChangeForAllNotInTarget;
  private ListBox enableSignedPush;
  private ListBox requireSignedPush;
  private ListBox rejectImplicitMerges;
  private ListBox privateByDefault;
  private ListBox enableReviewerByEmail;
  private ListBox matchAuthorToCommitterDate;
  private NpTextBox maxObjectSizeLimit;
  private Label effectiveMaxObjectSizeLimit;
  private Map<String, Map<String, HasEnabled>> pluginConfigWidgets;

  // Section: Contributor Agreements
  private ListBox contributorAgreements;
  private ListBox signedOffBy;

  private NpTextArea descTxt;
  private Button saveProject;

  private OnEditEnabler saveEnabler;

  public ProjectInfoScreen(Project.NameKey toShow) {
    super(toShow);
  }

  @Override
  protected void onInitUI() {
    super.onInitUI();

    Resources.I.style().ensureInjected();
    saveProject = new Button(AdminConstants.I.buttonSaveChanges());
    saveProject.setStyleName("");
    saveProject.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            doSave();
          }
        });

    ExtensionPanel extensionPanelTop =
        new ExtensionPanel(GerritUiExtensionPoint.PROJECT_INFO_SCREEN_TOP);
    extensionPanelTop.put(GerritUiExtensionPoint.Key.PROJECT_NAME, getProjectKey().get());
    add(extensionPanelTop);

    add(new ProjectDownloadPanel(getProjectKey().get(), true));

    initDescription();
    grid = new LabeledWidgetsGrid();
    pluginOptionsPanel = new FlowPanel();
    actionsGrid = new LabeledWidgetsGrid();
    initProjectOptions();
    initAgreements();
    add(grid);
    add(pluginOptionsPanel);
    add(saveProject);
    add(actionsGrid);

    ExtensionPanel extensionPanelBottom =
        new ExtensionPanel(GerritUiExtensionPoint.PROJECT_INFO_SCREEN_BOTTOM);
    extensionPanelBottom.put(GerritUiExtensionPoint.Key.PROJECT_NAME, getProjectKey().get());
    add(extensionPanelBottom);
  }

  @Override
  protected void onLoad() {
    super.onLoad();

    Project.NameKey project = getProjectKey();
    CallbackGroup cbg = new CallbackGroup();
    AccessMap.get(
        project,
        cbg.add(
            new GerritCallback<ProjectAccessInfo>() {
              @Override
              public void onSuccess(ProjectAccessInfo result) {
                isOwner = result.isOwner();
                configVisible = result.configVisible();
                enableForm();
                saveProject.setVisible(isOwner);
              }
            }));
    ProjectApi.getConfig(
        project,
        cbg.addFinal(
            new ScreenLoadCallback<ConfigInfo>(this) {
              @Override
              public void preDisplay(ConfigInfo result) {
                display(result);
              }
            }));

    savedPanel = INFO;
  }

  private void enableForm() {
    enableForm(isOwner);
  }

  private void enableForm(boolean isOwner) {
    state.setEnabled(isOwner);
    submitType.setEnabled(isOwner);
    setEnabledForUseContentMerge();
    newChangeForAllNotInTarget.setEnabled(isOwner);
    if (enableSignedPush != null) {
      enableSignedPush.setEnabled(isOwner);
    }
    if (requireSignedPush != null) {
      requireSignedPush.setEnabled(isOwner);
    }
    descTxt.setEnabled(isOwner);
    contributorAgreements.setEnabled(isOwner);
    signedOffBy.setEnabled(isOwner);
    requireChangeID.setEnabled(isOwner);
    rejectImplicitMerges.setEnabled(isOwner);
    privateByDefault.setEnabled(isOwner);
    maxObjectSizeLimit.setEnabled(isOwner);
    enableReviewerByEmail.setEnabled(isOwner);
    matchAuthorToCommitterDate.setEnabled(isOwner);

    if (pluginConfigWidgets != null) {
      for (Map<String, HasEnabled> widgetMap : pluginConfigWidgets.values()) {
        for (HasEnabled widget : widgetMap.values()) {
          widget.setEnabled(isOwner);
        }
      }
    }
  }

  private void initDescription() {
    final VerticalPanel vp = new VerticalPanel();
    vp.add(new SmallHeading(AdminConstants.I.headingDescription()));

    descTxt = new NpTextArea();
    descTxt.setVisibleLines(6);
    descTxt.setCharacterWidth(60);
    vp.add(descTxt);

    add(vp);
    saveEnabler = new OnEditEnabler(saveProject);
    saveEnabler.listenTo(descTxt);
  }

  private void initProjectOptions() {
    grid.addHeader(new SmallHeading(AdminConstants.I.headingProjectOptions()));

    state = new ListBox();
    for (ProjectState stateValue : ProjectState.values()) {
      state.addItem(Util.toLongString(stateValue), stateValue.name());
    }
    saveEnabler.listenTo(state);
    grid.add(AdminConstants.I.headingProjectState(), state);

    submitType = new ListBox();
    for (SubmitType type : SubmitType.values()) {
      submitType.addItem(Util.toLongString(type), type.name());
    }
    submitType.addChangeHandler(
        new ChangeHandler() {
          @Override
          public void onChange(ChangeEvent event) {
            setEnabledForUseContentMerge();
          }
        });
    saveEnabler.listenTo(submitType);
    grid.add(AdminConstants.I.headingProjectSubmitType(), submitType);

    contentMerge = newInheritedBooleanBox();
    saveEnabler.listenTo(contentMerge);
    grid.add(AdminConstants.I.useContentMerge(), contentMerge);

    newChangeForAllNotInTarget = newInheritedBooleanBox();
    saveEnabler.listenTo(newChangeForAllNotInTarget);
    grid.add(AdminConstants.I.createNewChangeForAllNotInTarget(), newChangeForAllNotInTarget);

    requireChangeID = newInheritedBooleanBox();
    saveEnabler.listenTo(requireChangeID);
    grid.addHtml(AdminConstants.I.requireChangeID(), requireChangeID);

    if (Gerrit.info().receive().enableSignedPush()) {
      enableSignedPush = newInheritedBooleanBox();
      saveEnabler.listenTo(enableSignedPush);
      grid.add(AdminConstants.I.enableSignedPush(), enableSignedPush);
      requireSignedPush = newInheritedBooleanBox();
      saveEnabler.listenTo(requireSignedPush);
      grid.add(AdminConstants.I.requireSignedPush(), requireSignedPush);
    }

    rejectImplicitMerges = newInheritedBooleanBox();
    saveEnabler.listenTo(rejectImplicitMerges);
    grid.addHtml(AdminConstants.I.rejectImplicitMerges(), rejectImplicitMerges);

    privateByDefault = newInheritedBooleanBox();
    saveEnabler.listenTo(privateByDefault);
    grid.addHtml(AdminConstants.I.privateByDefault(), privateByDefault);

    enableReviewerByEmail = newInheritedBooleanBox();
    saveEnabler.listenTo(enableReviewerByEmail);
    grid.addHtml(AdminConstants.I.enableReviewerByEmail(), enableReviewerByEmail);

    matchAuthorToCommitterDate = newInheritedBooleanBox();
    saveEnabler.listenTo(matchAuthorToCommitterDate);
    grid.addHtml(AdminConstants.I.matchAuthorToCommitterDate(), matchAuthorToCommitterDate);

    maxObjectSizeLimit = new NpTextBox();
    saveEnabler.listenTo(maxObjectSizeLimit);
    effectiveMaxObjectSizeLimit = new Label();
    effectiveMaxObjectSizeLimit.setStyleName(
        Gerrit.RESOURCES.css().maxObjectSizeLimitEffectiveLabel());
    HorizontalPanel p = new HorizontalPanel();
    p.add(maxObjectSizeLimit);
    p.add(effectiveMaxObjectSizeLimit);
    grid.addHtml(AdminConstants.I.headingMaxObjectSizeLimit(), p);
  }

  private static ListBox newInheritedBooleanBox() {
    ListBox box = new ListBox();
    for (InheritableBoolean b : InheritableBoolean.values()) {
      box.addItem(b.name(), b.name());
    }
    return box;
  }

  /**
   * Enables the {@link #contentMerge} checkbox if the selected submit type allows the usage of
   * content merge. If the submit type (currently only 'Fast Forward Only') does not allow content
   * merge the useContentMerge checkbox gets disabled.
   */
  private void setEnabledForUseContentMerge() {
    if (SubmitType.FAST_FORWARD_ONLY.equals(
        SubmitType.valueOf(submitType.getValue(submitType.getSelectedIndex())))) {
      contentMerge.setEnabled(false);
      InheritedBooleanInfo b = InheritedBooleanInfo.create();
      b.setConfiguredValue(InheritableBoolean.FALSE);
      setBool(contentMerge, b);
    } else {
      contentMerge.setEnabled(submitType.isEnabled());
    }
  }

  private void initAgreements() {
    grid.addHeader(new SmallHeading(AdminConstants.I.headingAgreements()));

    contributorAgreements = newInheritedBooleanBox();
    if (Gerrit.info().auth().useContributorAgreements()) {
      saveEnabler.listenTo(contributorAgreements);
      grid.add(AdminConstants.I.useContributorAgreements(), contributorAgreements);
    }

    signedOffBy = newInheritedBooleanBox();
    saveEnabler.listenTo(signedOffBy);
    grid.addHtml(AdminConstants.I.useSignedOffBy(), signedOffBy);
  }

  private void setSubmitType(SubmitType newSubmitType) {
    int index = -1;
    if (submitType != null) {
      for (int i = 0; i < submitType.getItemCount(); i++) {
        if (newSubmitType.name().equals(submitType.getValue(i))) {
          index = i;
          break;
        }
      }
      submitType.setSelectedIndex(index);
      setEnabledForUseContentMerge();
    }
  }

  private void setState(ProjectState newState) {
    if (state != null) {
      for (int i = 0; i < state.getItemCount(); i++) {
        if (newState.name().equals(state.getValue(i))) {
          state.setSelectedIndex(i);
          break;
        }
      }
    }
  }

  private void setBool(ListBox box, InheritedBooleanInfo inheritedBoolean) {
    if (box == null) {
      return;
    }
    int inheritedIndex = -1;
    for (int i = 0; i < box.getItemCount(); i++) {
      if (box.getValue(i).startsWith(InheritableBoolean.INHERIT.name())) {
        inheritedIndex = i;
      }
      if (box.getValue(i).startsWith(inheritedBoolean.configuredValue().name())) {
        box.setSelectedIndex(i);
      }
    }
    if (inheritedIndex >= 0) {
      if (Gerrit.info().gerrit().isAllProjects(getProjectKey())) {
        if (box.getSelectedIndex() == inheritedIndex) {
          for (int i = 0; i < box.getItemCount(); i++) {
            if (box.getValue(i).equals(InheritableBoolean.FALSE.name())) {
              box.setSelectedIndex(i);
              break;
            }
          }
        }
        box.removeItem(inheritedIndex);
      } else {
        box.setItemText(
            inheritedIndex,
            InheritableBoolean.INHERIT.name() + " (" + inheritedBoolean.inheritedValue() + ")");
      }
    }
  }

  private static InheritableBoolean getBool(ListBox box) {
    int i = box.getSelectedIndex();
    if (i >= 0) {
      final String selectedValue = box.getValue(i);
      if (selectedValue.startsWith(InheritableBoolean.INHERIT.name())) {
        return InheritableBoolean.INHERIT;
      }
      return InheritableBoolean.valueOf(selectedValue);
    }
    return InheritableBoolean.INHERIT;
  }

  void display(ConfigInfo result) {
    descTxt.setText(result.description());
    setBool(contributorAgreements, result.useContributorAgreements());
    setBool(signedOffBy, result.useSignedOffBy());
    setBool(contentMerge, result.useContentMerge());
    setBool(newChangeForAllNotInTarget, result.createNewChangeForAllNotInTarget());
    setBool(requireChangeID, result.requireChangeId());
    if (Gerrit.info().receive().enableSignedPush()) {
      setBool(enableSignedPush, result.enableSignedPush());
      setBool(requireSignedPush, result.requireSignedPush());
    }
    setBool(rejectImplicitMerges, result.rejectImplicitMerges());
    setBool(privateByDefault, result.privateByDefault());
    setBool(enableReviewerByEmail, result.enableReviewerByEmail());
    setBool(matchAuthorToCommitterDate, result.matchAuthorToCommitterDate());
    setSubmitType(result.submitType());
    setState(result.state());
    maxObjectSizeLimit.setText(result.maxObjectSizeLimit().configuredValue());
    if (result.maxObjectSizeLimit().inheritedValue() != null) {
      effectiveMaxObjectSizeLimit.setVisible(true);
      effectiveMaxObjectSizeLimit.setText(
          AdminMessages.I.effectiveMaxObjectSizeLimit(result.maxObjectSizeLimit().value()));
      effectiveMaxObjectSizeLimit.setTitle(
          AdminMessages.I.globalMaxObjectSizeLimit(result.maxObjectSizeLimit().inheritedValue()));
    } else {
      effectiveMaxObjectSizeLimit.setVisible(false);
    }

    saveProject.setEnabled(false);
    initPluginOptions(result);
    initProjectActions(result);
  }

  private void initPluginOptions(ConfigInfo info) {
    pluginOptionsPanel.clear();
    pluginConfigWidgets = new HashMap<>();

    for (String pluginName : info.pluginConfig().keySet()) {
      Map<String, HasEnabled> widgetMap = new HashMap<>();
      pluginConfigWidgets.put(pluginName, widgetMap);
      LabeledWidgetsGrid g = new LabeledWidgetsGrid();
      g.addHeader(new SmallHeading(AdminMessages.I.pluginProjectOptionsTitle(pluginName)));
      pluginOptionsPanel.add(g);
      NativeMap<ConfigParameterInfo> pluginConfig = info.pluginConfig(pluginName);
      pluginConfig.copyKeysIntoChildren("name");
      for (ConfigParameterInfo param : Natives.asList(pluginConfig.values())) {
        HasEnabled w;
        switch (param.type()) {
          case "STRING":
          case "INT":
          case "LONG":
            w = renderTextBox(g, param);
            break;
          case "BOOLEAN":
            w = renderCheckBox(g, param);
            break;
          case "LIST":
            w = renderListBox(g, param);
            break;
          case "ARRAY":
            w = renderStringListPanel(g, param);
            break;
          default:
            throw new UnsupportedOperationException("unsupported widget type");
        }
        if (param.editable()) {
          widgetMap.put(param.name(), w);
        } else {
          w.setEnabled(false);
        }
      }
    }

    enableForm();
  }

  private TextBox renderTextBox(LabeledWidgetsGrid g, ConfigParameterInfo param) {
    NpTextBox textBox = param.type().equals("STRING") ? new NpTextBox() : new NpIntTextBox();
    if (param.inheritable()) {
      textBox.setValue(param.configuredValue());
      Label inheritedLabel =
          new Label(AdminMessages.I.pluginProjectInheritedValue(param.inheritedValue()));
      inheritedLabel.setStyleName(Gerrit.RESOURCES.css().pluginProjectConfigInheritedValue());
      HorizontalPanel p = new HorizontalPanel();
      p.add(textBox);
      p.add(inheritedLabel);
      addWidget(g, p, param);
    } else {
      textBox.setValue(param.value());
      addWidget(g, textBox, param);
    }
    saveEnabler.listenTo(textBox);
    return textBox;
  }

  private CheckBox renderCheckBox(LabeledWidgetsGrid g, ConfigParameterInfo param) {
    CheckBox checkBox = new CheckBox(getDisplayName(param));
    checkBox.setValue(Boolean.parseBoolean(param.value()));
    HorizontalPanel p = new HorizontalPanel();
    p.add(checkBox);
    if (param.description() != null) {
      Image infoImg = new Image(Gerrit.RESOURCES.info());
      infoImg.setTitle(param.description());
      p.add(infoImg);
    }
    if (param.warning() != null) {
      Image warningImg = new Image(Gerrit.RESOURCES.warning());
      warningImg.setTitle(param.warning());
      p.add(warningImg);
    }
    g.add((String) null, p);
    saveEnabler.listenTo(checkBox);
    return checkBox;
  }

  private ListBox renderListBox(LabeledWidgetsGrid g, ConfigParameterInfo param) {
    if (param.permittedValues() == null) {
      return null;
    }
    ListBox listBox = new ListBox();
    if (param.inheritable()) {
      listBox.addItem(AdminMessages.I.pluginProjectInheritedListValue(param.inheritedValue()));
      if (param.configuredValue() == null) {
        listBox.setSelectedIndex(0);
      }
      for (int i = 0; i < param.permittedValues().length(); i++) {
        String pv = param.permittedValues().get(i);
        listBox.addItem(pv);
        if (pv.equals(param.configuredValue())) {
          listBox.setSelectedIndex(i + 1);
        }
      }
    } else {
      for (int i = 0; i < param.permittedValues().length(); i++) {
        String pv = param.permittedValues().get(i);
        listBox.addItem(pv);
        if (pv.equals(param.value())) {
          listBox.setSelectedIndex(i);
        }
      }
    }

    if (param.editable()) {
      saveEnabler.listenTo(listBox);
      addWidget(g, listBox, param);
    } else {
      listBox.setEnabled(false);

      if (param.inheritable() && listBox.getSelectedIndex() != 0) {
        // the inherited value is not selected,
        // since the listBox is disabled the inherited value cannot be
        // seen and we have to display it explicitly
        Label inheritedLabel =
            new Label(AdminMessages.I.pluginProjectInheritedValue(param.inheritedValue()));
        inheritedLabel.setStyleName(Gerrit.RESOURCES.css().pluginProjectConfigInheritedValue());
        HorizontalPanel p = new HorizontalPanel();
        p.add(listBox);
        p.add(inheritedLabel);
        addWidget(g, p, param);
      } else {
        addWidget(g, listBox, param);
      }
    }

    return listBox;
  }

  private StringListPanel renderStringListPanel(LabeledWidgetsGrid g, ConfigParameterInfo param) {
    StringListPanel p =
        new StringListPanel(null, Arrays.asList(getDisplayName(param)), saveProject, false);
    List<List<String>> values = new ArrayList<>();
    for (String v : Natives.asList(param.values())) {
      values.add(Arrays.asList(v));
    }
    p.display(values);
    if (!param.editable()) {
      p.setEnabled(false);
    }
    addWidget(g, p, param);
    return p;
  }

  private void addWidget(LabeledWidgetsGrid g, Widget w, ConfigParameterInfo param) {
    if (param.description() != null || param.warning() != null) {
      HorizontalPanel p = new HorizontalPanel();
      p.add(new Label(getDisplayName(param)));
      if (param.description() != null) {
        Image infoImg = new Image(Gerrit.RESOURCES.info());
        infoImg.setTitle(param.description());
        p.add(infoImg);
      }
      if (param.warning() != null) {
        Image warningImg = new Image(Gerrit.RESOURCES.warning());
        warningImg.setTitle(param.warning());
        p.add(warningImg);
      }
      p.add(new Label(":"));
      g.add(p, w);
    } else {
      g.add(getDisplayName(param), w);
    }
  }

  private String getDisplayName(ConfigParameterInfo param) {
    return param.displayName() != null ? param.displayName() : param.name();
  }

  private void initProjectActions(ConfigInfo info) {
    actionsGrid.clear(true);
    actionsGrid.removeAllRows();
    boolean showCreateChange = Gerrit.isSignedIn();

    NativeMap<ActionInfo> actions = info.actions();
    if (actions == null) {
      actions = NativeMap.create().cast();
    }
    if (actions.isEmpty() && !showCreateChange) {
      return;
    }
    actions.copyKeysIntoChildren("id");
    actionsGrid.addHeader(new SmallHeading(AdminConstants.I.headingProjectCommands()));
    FlowPanel actionsPanel = new FlowPanel();
    actionsPanel.setStyleName(Gerrit.RESOURCES.css().projectActions());
    actionsPanel.setVisible(true);
    actionsGrid.add(AdminConstants.I.headingCommands(), actionsPanel);

    for (String id : actions.keySet()) {
      actionsPanel.add(new ActionButton(getProjectKey(), actions.get(id)));
    }

    // TODO: The user should have create permission on the branch referred to by
    // HEAD. This would have to happen on the server side.
    if (showCreateChange) {
      actionsPanel.add(createChangeAction());
    }

    if (isOwner && configVisible) {
      actionsPanel.add(createEditConfigAction());
    }
  }

  private Button createChangeAction() {
    final Button createChange = new Button(AdminConstants.I.buttonCreateChange());
    createChange.setStyleName("");
    createChange.setTitle(AdminConstants.I.buttonCreateChangeDescription());
    createChange.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            CreateChangeAction.call(createChange, getProjectKey().get());
          }
        });
    return createChange;
  }

  private Button createEditConfigAction() {
    final Button editConfig = new Button(AdminConstants.I.buttonEditConfig());
    editConfig.setStyleName("");
    editConfig.setTitle(AdminConstants.I.buttonEditConfigDescription());
    editConfig.addClickHandler(
        new ClickHandler() {
          @Override
          public void onClick(ClickEvent event) {
            EditConfigAction.call(editConfig, getProjectKey());
          }
        });
    return editConfig;
  }

  private void doSave() {
    enableForm(false);
    saveProject.setEnabled(false);
    InheritableBoolean esp = enableSignedPush != null ? getBool(enableSignedPush) : null;
    InheritableBoolean rsp = requireSignedPush != null ? getBool(requireSignedPush) : null;
    ProjectApi.setConfig(
        getProjectKey(),
        descTxt.getText().trim(),
        getBool(contributorAgreements),
        getBool(contentMerge),
        getBool(signedOffBy),
        getBool(newChangeForAllNotInTarget),
        getBool(requireChangeID),
        esp,
        rsp,
        getBool(rejectImplicitMerges),
        getBool(privateByDefault),
        getBool(enableReviewerByEmail),
        getBool(matchAuthorToCommitterDate),
        maxObjectSizeLimit.getText().trim(),
        SubmitType.valueOf(submitType.getValue(submitType.getSelectedIndex())),
        ProjectState.valueOf(state.getValue(state.getSelectedIndex())),
        getPluginConfigValues(),
        new GerritCallback<ConfigInfo>() {
          @Override
          public void onSuccess(ConfigInfo result) {
            enableForm();
            display(result);
          }

          @Override
          public void onFailure(Throwable caught) {
            enableForm();
            super.onFailure(caught);
          }
        });
  }

  private Map<String, Map<String, ConfigParameterValue>> getPluginConfigValues() {
    Map<String, Map<String, ConfigParameterValue>> pluginConfigValues =
        new HashMap<>(pluginConfigWidgets.size());
    for (Entry<String, Map<String, HasEnabled>> e : pluginConfigWidgets.entrySet()) {
      Map<String, ConfigParameterValue> values = new HashMap<>(e.getValue().size());
      pluginConfigValues.put(e.getKey(), values);
      for (Entry<String, HasEnabled> e2 : e.getValue().entrySet()) {
        HasEnabled widget = e2.getValue();
        if (widget instanceof TextBox) {
          values.put(
              e2.getKey(),
              ConfigParameterValue.create().value(((TextBox) widget).getValue().trim()));
        } else if (widget instanceof CheckBox) {
          values.put(
              e2.getKey(),
              ConfigParameterValue.create()
                  .value(Boolean.toString(((CheckBox) widget).getValue())));
        } else if (widget instanceof ListBox) {
          ListBox listBox = (ListBox) widget;
          // the inherited value is at index 0,
          // if it is selected no value should be set on this project
          String value =
              listBox.getSelectedIndex() > 0 ? listBox.getValue(listBox.getSelectedIndex()) : null;
          values.put(e2.getKey(), ConfigParameterValue.create().value(value));
        } else if (widget instanceof StringListPanel) {
          values.put(
              e2.getKey(),
              ConfigParameterValue.create()
                  .values(((StringListPanel) widget).getValues(0).toArray(new String[] {})));
        } else {
          throw new UnsupportedOperationException("unsupported widget type");
        }
      }
    }
    return pluginConfigValues;
  }

  public static class ProjectDownloadPanel extends DownloadPanel {
    public ProjectDownloadPanel(String project, boolean isAllowsAnonymous) {
      super(project, isAllowsAnonymous);
    }

    @Override
    protected List<DownloadCommandInfo> getCommands(DownloadSchemeInfo schemeInfo) {
      return schemeInfo.cloneCommands(project);
    }
  }

  private static class LabeledWidgetsGrid extends FlexTable {
    private String labelSuffix;

    LabeledWidgetsGrid() {
      super();
      labelSuffix = ":";
    }

    private void addHeader(Widget widget) {
      int row = getRowCount();
      insertRow(row);
      setWidget(row, 0, widget);
      getCellFormatter().getElement(row, 0).setAttribute("colSpan", "2");
    }

    private void add(String label, boolean labelIsHtml, Widget widget) {
      int row = getRowCount();
      insertRow(row);
      if (label != null) {
        if (labelIsHtml) {
          setHTML(row, 0, label + labelSuffix);
        } else {
          setText(row, 0, label + labelSuffix);
        }
      }
      setWidget(row, 1, widget);
    }

    public void add(String label, Widget widget) {
      add(label, false, widget);
    }

    public void addHtml(String label, Widget widget) {
      add(label, true, widget);
    }

    public void add(Widget label, Widget widget) {
      int row = getRowCount();
      insertRow(row);
      setWidget(row, 0, label);
      setWidget(row, 1, widget);
    }
  }
}
