// Copyright (C) 2013 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.server.config;

import static java.util.stream.Collectors.toList;

import com.google.gerrit.extensions.annotations.ExtensionPoint;
import com.google.gerrit.extensions.api.projects.ConfigValue;
import com.google.gerrit.extensions.api.projects.ProjectConfigEntryType;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.DynamicMap.Entry;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.ProvisionException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ExtensionPoint
public class ProjectConfigEntry {
  private final String displayName;
  private final String description;
  private final boolean inheritable;
  private final String defaultValue;
  private final ProjectConfigEntryType type;
  private final List<String> permittedValues;

  public ProjectConfigEntry(String displayName, String defaultValue) {
    this(displayName, defaultValue, false);
  }

  public ProjectConfigEntry(String displayName, String defaultValue, boolean inheritable) {
    this(displayName, defaultValue, inheritable, null);
  }

  public ProjectConfigEntry(
      String displayName, String defaultValue, boolean inheritable, String description) {
    this(displayName, defaultValue, ProjectConfigEntryType.STRING, null, inheritable, description);
  }

  public ProjectConfigEntry(String displayName, int defaultValue) {
    this(displayName, defaultValue, false);
  }

  public ProjectConfigEntry(String displayName, int defaultValue, boolean inheritable) {
    this(displayName, defaultValue, inheritable, null);
  }

  public ProjectConfigEntry(
      String displayName, int defaultValue, boolean inheritable, String description) {
    this(
        displayName,
        Integer.toString(defaultValue),
        ProjectConfigEntryType.INT,
        null,
        inheritable,
        description);
  }

  public ProjectConfigEntry(String displayName, long defaultValue) {
    this(displayName, defaultValue, false);
  }

  public ProjectConfigEntry(String displayName, long defaultValue, boolean inheritable) {
    this(displayName, defaultValue, inheritable, null);
  }

  public ProjectConfigEntry(
      String displayName, long defaultValue, boolean inheritable, String description) {
    this(
        displayName,
        Long.toString(defaultValue),
        ProjectConfigEntryType.LONG,
        null,
        inheritable,
        description);
  }

  // For inheritable boolean use 'LIST' type with InheritableBoolean
  public ProjectConfigEntry(String displayName, boolean defaultValue) {
    this(displayName, defaultValue, null);
  }

  // For inheritable boolean use 'LIST' type with InheritableBoolean
  public ProjectConfigEntry(String displayName, boolean defaultValue, String description) {
    this(
        displayName,
        Boolean.toString(defaultValue),
        ProjectConfigEntryType.BOOLEAN,
        null,
        false,
        description);
  }

  public ProjectConfigEntry(String displayName, String defaultValue, List<String> permittedValues) {
    this(displayName, defaultValue, permittedValues, false);
  }

  public ProjectConfigEntry(
      String displayName, String defaultValue, List<String> permittedValues, boolean inheritable) {
    this(displayName, defaultValue, permittedValues, inheritable, null);
  }

  public ProjectConfigEntry(
      String displayName,
      String defaultValue,
      List<String> permittedValues,
      boolean inheritable,
      String description) {
    this(
        displayName,
        defaultValue,
        ProjectConfigEntryType.LIST,
        permittedValues,
        inheritable,
        description);
  }

  public <T extends Enum<?>> ProjectConfigEntry(
      String displayName, T defaultValue, Class<T> permittedValues) {
    this(displayName, defaultValue, permittedValues, false);
  }

  public <T extends Enum<?>> ProjectConfigEntry(
      String displayName, T defaultValue, Class<T> permittedValues, boolean inheritable) {
    this(displayName, defaultValue, permittedValues, inheritable, null);
  }

  public <T extends Enum<?>> ProjectConfigEntry(
      String displayName,
      T defaultValue,
      Class<T> permittedValues,
      boolean inheritable,
      String description) {
    this(
        displayName,
        defaultValue.name(),
        ProjectConfigEntryType.LIST,
        Arrays.stream(permittedValues.getEnumConstants()).map(Enum::name).collect(toList()),
        inheritable,
        description);
  }

  public ProjectConfigEntry(
      String displayName,
      String defaultValue,
      ProjectConfigEntryType type,
      List<String> permittedValues,
      boolean inheritable,
      String description) {
    this.displayName = displayName;
    this.defaultValue = defaultValue;
    this.type = type;
    this.permittedValues = permittedValues;
    this.inheritable = inheritable;
    this.description = description;
    if (type == ProjectConfigEntryType.ARRAY && inheritable) {
      throw new ProvisionException("ARRAY doesn't support inheritable values");
    }
  }

  public String getDisplayName() {
    return displayName;
  }

  public String getDescription() {
    return description;
  }

  public boolean isInheritable() {
    return inheritable;
  }

  public String getDefaultValue() {
    return defaultValue;
  }

  public ProjectConfigEntryType getType() {
    return type;
  }

  public List<String> getPermittedValues() {
    return permittedValues;
  }

  /**
   * @param project project state.
   * @return whether the project is editable.
   */
  public boolean isEditable(ProjectState project) {
    return true;
  }

  /**
   * @param project project state.
   * @return any warning associated with the project.
   */
  public String getWarning(ProjectState project) {
    return null;
  }

  /**
   * Called before the project config is updated. To modify the value before the project config is
   * updated, override this method and return the modified value. Default implementation returns the
   * same value.
   *
   * @param configValue the original configValue that was entered.
   * @return the modified configValue.
   */
  public ConfigValue preUpdate(ConfigValue configValue) {
    return configValue;
  }

  /**
   * Called after reading the project config value. To modify the value before returning it to the
   * client, override this method and return the modified value. Default implementation returns the
   * same value.
   *
   * @param project the project.
   * @param value the actual value of the config entry (computed out of the configured value, the
   *     inherited value and the default value).
   * @return the modified value.
   */
  public String onRead(ProjectState project, String value) {
    return value;
  }

  /**
   * Called after reading the project config value of type ARRAY. To modify the values before
   * returning it to the client, override this method and return the modified values. Default
   * implementation returns the same values.
   *
   * @param project the project.
   * @param values the actual values of the config entry (computed out of the configured value, the
   *     inherited value and the default value).
   * @return the modified values.
   */
  public List<String> onRead(ProjectState project, List<String> values) {
    return values;
  }

  /**
   * Called after a project config is updated.
   *
   * @param project project name.
   * @param oldValue old entry value.
   * @param newValue new entry value.
   */
  public void onUpdate(Project.NameKey project, String oldValue, String newValue) {}

  /**
   * Called after a project config is updated.
   *
   * @param project project name.
   * @param oldValue old entry value.
   * @param newValue new entry value.
   */
  public void onUpdate(Project.NameKey project, Boolean oldValue, Boolean newValue) {}

  /**
   * Called after a project config is updated.
   *
   * @param project project name.
   * @param oldValue old entry value.
   * @param newValue new entry value.
   */
  public void onUpdate(Project.NameKey project, Integer oldValue, Integer newValue) {}

  /**
   * Called after a project config is updated.
   *
   * @param project project name.
   * @param oldValue old entry value.
   * @param newValue new entry value.
   */
  public void onUpdate(Project.NameKey project, Long oldValue, Long newValue) {}

  public static class UpdateChecker implements GitReferenceUpdatedListener {
    private static final Logger log = LoggerFactory.getLogger(UpdateChecker.class);

    private final GitRepositoryManager repoManager;
    private final DynamicMap<ProjectConfigEntry> pluginConfigEntries;

    @Inject
    UpdateChecker(
        GitRepositoryManager repoManager, DynamicMap<ProjectConfigEntry> pluginConfigEntries) {
      this.repoManager = repoManager;
      this.pluginConfigEntries = pluginConfigEntries;
    }

    @Override
    public void onGitReferenceUpdated(Event event) {
      Project.NameKey p = new Project.NameKey(event.getProjectName());
      if (!event.getRefName().equals(RefNames.REFS_CONFIG)) {
        return;
      }

      try {
        ProjectConfig oldCfg = parseConfig(p, event.getOldObjectId());
        ProjectConfig newCfg = parseConfig(p, event.getNewObjectId());
        if (oldCfg != null && newCfg != null) {
          for (Entry<ProjectConfigEntry> e : pluginConfigEntries) {
            ProjectConfigEntry configEntry = e.getProvider().get();
            String newValue = getValue(newCfg, e);
            String oldValue = getValue(oldCfg, e);
            if ((newValue == null && oldValue == null)
                || (newValue != null && newValue.equals(oldValue))) {
              return;
            }

            switch (configEntry.getType()) {
              case BOOLEAN:
                configEntry.onUpdate(p, toBoolean(oldValue), toBoolean(newValue));
                break;
              case INT:
                configEntry.onUpdate(p, toInt(oldValue), toInt(newValue));
                break;
              case LONG:
                configEntry.onUpdate(p, toLong(oldValue), toLong(newValue));
                break;
              case LIST:
              case STRING:
              case ARRAY:
              default:
                configEntry.onUpdate(p, oldValue, newValue);
            }
          }
        }
      } catch (IOException | ConfigInvalidException e) {
        log.error(
            String.format("Failed to check if plugin config of project %s was updated.", p.get()),
            e);
      }
    }

    private ProjectConfig parseConfig(Project.NameKey p, String idStr)
        throws IOException, ConfigInvalidException, RepositoryNotFoundException {
      ObjectId id = ObjectId.fromString(idStr);
      if (ObjectId.zeroId().equals(id)) {
        return null;
      }
      try (Repository repo = repoManager.openRepository(p)) {
        ProjectConfig pc = new ProjectConfig(p);
        pc.load(repo, id);
        return pc;
      }
    }

    private static String getValue(ProjectConfig cfg, Entry<ProjectConfigEntry> e) {
      String value = cfg.getPluginConfig(e.getPluginName()).getString(e.getExportName());
      if (value == null) {
        value = e.getProvider().get().getDefaultValue();
      }
      return value;
    }
  }

  private static Boolean toBoolean(String value) {
    return value != null ? Boolean.parseBoolean(value) : null;
  }

  private static Integer toInt(String value) {
    return value != null ? Integer.parseInt(value) : null;
  }

  private static Long toLong(String value) {
    return value != null ? Long.parseLong(value) : null;
  }
}
