// Copyright (C) 2021 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.project;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.SubmitRequirement;
import com.google.gerrit.entities.SubmitRequirementResult;
import com.google.gerrit.metrics.Counter1;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.server.logging.Metadata;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeData.StorageConstraint;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * A utility class for different operations related to {@link
 * com.google.gerrit.entities.SubmitRequirement}s.
 */
@Singleton
public class SubmitRequirementsUtil {

  /**
   * Submit requirement name can only contain alphanumeric characters or hyphen. Name cannot start
   * with a hyphen or number.
   */
  private static final Pattern SUBMIT_REQ_NAME_PATTERN = Pattern.compile("[a-zA-Z][a-zA-Z0-9\\-]*");

  @Singleton
  static class Metrics {
    final Counter1<String> submitRequirementsMatchingWithLegacy;
    final Counter1<String> submitRequirementsMismatchingWithLegacy;
    final Counter1<String> legacyNotInSrs;
    final Counter1<String> srsNotInLegacy;

    @Inject
    Metrics(MetricMaker metricMaker) {
      submitRequirementsMatchingWithLegacy =
          metricMaker.newCounter(
              "change/submit_requirements/matching_with_legacy",
              new Description(
                      "Total number of times there was a legacy and non-legacy "
                          + "submit requirements with the same name for a change, "
                          + "and the evaluation of both requirements had the same result "
                          + "w.r.t. change submittability.")
                  .setRate()
                  .setUnit("count"),
              Field.ofString("sr_name", Metadata.Builder::submitRequirementName)
                  .description("Submit requirement name")
                  .build());
      submitRequirementsMismatchingWithLegacy =
          metricMaker.newCounter(
              "change/submit_requirements/mismatching_with_legacy",
              new Description(
                      "Total number of times there was a legacy and non-legacy "
                          + "submit requirements with the same name for a change, "
                          + "and the evaluation of both requirements had a different result "
                          + "w.r.t. change submittability.")
                  .setRate()
                  .setUnit("count"),
              Field.ofString("sr_name", Metadata.Builder::submitRequirementName)
                  .description("Submit requirement name")
                  .build());
      legacyNotInSrs =
          metricMaker.newCounter(
              "change/submit_requirements/legacy_not_in_srs",
              new Description(
                      "Total number of times there was a legacy submit requirement result "
                          + "but not a project config requirement with the same name for a change.")
                  .setRate()
                  .setUnit("count"),
              Field.ofString("sr_name", Metadata.Builder::submitRequirementName)
                  .description("Submit requirement name")
                  .build());
      srsNotInLegacy =
          metricMaker.newCounter(
              "change/submit_requirements/srs_not_in_legacy",
              new Description(
                      "Total number of times there was a project config submit requirement "
                          + "result but not a legacy requirement with the same name for a change.")
                  .setRate()
                  .setUnit("count"),
              Field.ofString("sr_name", Metadata.Builder::submitRequirementName)
                  .description("Submit requirement name")
                  .build());
    }
  }

  private final Metrics metrics;

  @Inject
  public SubmitRequirementsUtil(Metrics metrics) {
    this.metrics = metrics;
  }

  /**
   * Merge legacy and non-legacy submit requirement results. If both input maps have submit
   * requirements with the same name and fulfillment status (according to {@link
   * SubmitRequirementResult#fulfilled()}), we eliminate the entry from the {@code
   * legacyRequirements} input map and only include the one from the {@code
   * projectConfigRequirements} in the result.
   *
   * @param projectConfigRequirements map of {@link SubmitRequirement} to {@link
   *     SubmitRequirementResult} containing results for submit requirements stored in the
   *     project.config.
   * @param legacyRequirements map of {@link SubmitRequirement} to {@link SubmitRequirementResult}
   *     containing the results of converting legacy submit records to submit requirements.
   * @return a map that is the result of merging both input maps, while eliminating requirements
   *     with the same name and status.
   */
  public ImmutableMap<SubmitRequirement, SubmitRequirementResult>
      mergeLegacyAndNonLegacyRequirements(
          Map<SubmitRequirement, SubmitRequirementResult> projectConfigRequirements,
          Map<SubmitRequirement, SubmitRequirementResult> legacyRequirements,
          ChangeData cd) {
    // Cannot use ImmutableMap.Builder here since entries in the map may be overridden.
    Map<SubmitRequirement, SubmitRequirementResult> result = new HashMap<>();
    result.putAll(projectConfigRequirements);
    Map<String, SubmitRequirementResult> requirementsByName =
        projectConfigRequirements.entrySet().stream()
            // filter out legacy entries as a safety guard for duplicate entries
            // (projectConfigRequirements should not contain legacy entries)
            // TODO(ghareeb): remove the filter statement
            .filter(entry -> !entry.getValue().isLegacy())
            .collect(Collectors.toMap(sr -> sr.getKey().name().toLowerCase(), sr -> sr.getValue()));
    for (Map.Entry<SubmitRequirement, SubmitRequirementResult> legacy :
        legacyRequirements.entrySet()) {
      String srName = legacy.getKey().name().toLowerCase();
      SubmitRequirementResult projectConfigResult = requirementsByName.get(srName);
      SubmitRequirementResult legacyResult = legacy.getValue();
      // If there's no project config requirement with the same name as the legacy requirement
      // then add the legacy SR to the result. There is no mismatch in results in this case.
      if (projectConfigResult == null) {
        result.put(legacy.getKey(), legacy.getValue());
        if (shouldReportMetric(cd)) {
          metrics.legacyNotInSrs.increment(srName);
        }
        continue;
      }
      if (matchByStatus(projectConfigResult, legacyResult)) {
        // There exists a project config SR with the same name as the legacy SR, and they are
        // matching in result. No need to include the legacy SR in the output since the project
        // config SR is already there.
        if (shouldReportMetric(cd)) {
          metrics.submitRequirementsMatchingWithLegacy.increment(srName);
        }
        continue;
      }
      // There exists a project config SR with the same name as the legacy SR but they are not
      // matching in their result. Increment the mismatch count and add the legacy SR to the result.
      if (shouldReportMetric(cd)) {
        metrics.submitRequirementsMismatchingWithLegacy.increment(srName);
      }
      result.put(legacy.getKey(), legacy.getValue());
    }
    Set<String> legacyNames =
        legacyRequirements.keySet().stream()
            .map(SubmitRequirement::name)
            .map(String::toLowerCase)
            .collect(Collectors.toSet());
    for (String projectConfigSrName : requirementsByName.keySet()) {
      if (!legacyNames.contains(projectConfigSrName) && shouldReportMetric(cd)) {
        metrics.srsNotInLegacy.increment(projectConfigSrName);
      }
    }

    return ImmutableMap.copyOf(result);
  }

  /** Validates the name of submit requirements. */
  public static void validateName(@Nullable String name) throws IllegalArgumentException {
    if (name == null || name.isEmpty()) {
      throw new IllegalArgumentException("Empty submit requirement name");
    }
    if (!SUBMIT_REQ_NAME_PATTERN.matcher(name).matches()) {
      throw new IllegalArgumentException(
          String.format(
              "Illegal submit requirement name \"%s\". Name can only consist of "
                  + "alphanumeric characters and '-'. Name cannot start with '-' or number.",
              name));
    }
  }

  private static boolean shouldReportMetric(ChangeData cd) {
    // We only care about recording differences in old and new requirements for open changes
    // that did not have their data retrieved from the (potentially stale) change index.
    return cd.change().isNew() && cd.getStorageConstraint() == StorageConstraint.NOTEDB_ONLY;
  }

  /** Returns true if both input results are equal in allowing/disallowing change submission. */
  private static boolean matchByStatus(SubmitRequirementResult r1, SubmitRequirementResult r2) {
    return r1.fulfilled() == r2.fulfilled();
  }
}
