// 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.plugins.codeowners.metrics;

import com.google.gerrit.metrics.Counter0;
import com.google.gerrit.metrics.Counter1;
import com.google.gerrit.metrics.Counter3;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Description.Units;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.Histogram0;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.Timer0;
import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.server.logging.Metadata;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/** Metrics of the code-owners plugin. */
@Singleton
public class CodeOwnerMetrics {
  // latency metrics
  public final Timer1<String> addChangeMessageOnAddReviewer;
  public final Timer0 computeFileStatus;
  public final Timer1<Boolean> computeFileStatuses;
  public final Timer0 computeOwnedPaths;
  public final Timer0 computePatchSetApprovals;
  public final Timer0 extendChangeMessageOnPostReview;
  public final Timer0 getChangedFiles;
  public final Timer0 prepareFileStatusComputation;
  public final Timer0 prepareFileStatusComputationForAccount;
  public final Timer0 resolveCodeOwnerConfig;
  public final Timer0 resolveCodeOwnerConfigImport;
  public final Timer0 resolveCodeOwnerConfigImports;
  public final Timer0 resolveCodeOwnerReferences;
  public final Timer0 resolvePathCodeOwners;
  public final Timer0 runCodeOwnerSubmitRule;

  // code owner config metrics
  public final Histogram0 codeOwnerCacheReadsPerChange;
  public final Histogram0 codeOwnerConfigBackendReadsPerChange;
  public final Histogram0 codeOwnerConfigCacheReadsPerChange;
  public final Histogram0 codeOwnerResolutionsPerChange;
  public final Timer1<String> loadCodeOwnerConfig;
  public final Timer0 readCodeOwnerConfig;
  public final Timer1<String> parseCodeOwnerConfig;

  // counter metrics
  public final Counter0 countCodeOwnerCacheReads;
  public final Counter0 countCodeOwnerConfigReads;
  public final Counter0 countCodeOwnerConfigCacheReads;
  public final Counter3<ValidationTrigger, ValidationResult, Boolean>
      countCodeOwnerConfigValidations;
  public final Counter0 countCodeOwnerResolutions;
  public final Counter1<String> countCodeOwnerSubmitRuleErrors;
  public final Counter0 countCodeOwnerSubmitRuleRuns;
  public final Counter1<Boolean> countCodeOwnerSuggestions;
  public final Counter3<String, String, String> countInvalidCodeOwnerConfigFiles;

  private final MetricMaker metricMaker;

  @Inject
  CodeOwnerMetrics(MetricMaker metricMaker) {
    this.metricMaker = metricMaker;

    // latency metrics
    this.addChangeMessageOnAddReviewer =
        createTimer(
            "add_change_message_on_add_reviewer",
            "Latency for adding a change message with the owned path when a code owner is added as"
                + " a reviewer",
            Field.ofString("post_type", (metadataBuilder, fieldValue) -> {})
                .description(
                    "Whether the change message was posted synchronously or asynchronously.")
                .build());
    this.computeFileStatus =
        createTimer("compute_file_status", "Latency for computing the file status of one file");
    this.computeFileStatuses =
        createTimer(
            "compute_file_statuses",
            "Latency for computing file statuses for all files in a change",
            Field.ofBoolean("sticky_approvals", (metadataBuilder, stickyApprovals) -> {})
                .description("Whether sticky approvals on file level are enabled.")
                .build());
    this.computeOwnedPaths =
        createTimer(
            "compute_owned_paths",
            "Latency for computing the files in a change that are owned by a user");
    this.computePatchSetApprovals =
        createTimer(
            "compute_patch_set_approvals",
            "Latency for computing the approvals of the current patch set");
    this.extendChangeMessageOnPostReview =
        createTimer(
            "extend_change_message_on_post_review",
            "Latency for extending the change message with the owned path when a code owner"
                + " approval is applied");
    this.getChangedFiles =
        createTimer("get_changed_files", "Latency for getting changed files from diff cache");
    this.prepareFileStatusComputation =
        createTimer(
            "prepare_file_status_computation", "Latency for preparing the file status computation");
    this.prepareFileStatusComputationForAccount =
        createTimer(
            "compute_file_statuses_for_account",
            "Latency for computing file statuses for an account");
    this.resolveCodeOwnerConfig =
        createTimer("resolve_code_owner_config", "Latency for resolving a code owner config file");
    this.resolveCodeOwnerConfigImport =
        createTimer(
            "resolve_code_owner_config_import",
            "Latency for resolving an import of a code owner config file");
    this.resolveCodeOwnerConfigImports =
        createTimer(
            "resolve_code_owner_config_imports",
            "Latency for resolving all imports of a code owner config file");
    this.resolveCodeOwnerReferences =
        createTimer(
            "resolve_code_owner_references", "Latency for resolving the code owner references");
    this.resolvePathCodeOwners =
        createTimer("resolve_path_code_owners", "Latency for resolving the code owners of a path");
    this.runCodeOwnerSubmitRule =
        createTimer("run_code_owner_submit_rule", "Latency for running the code owner submit rule");

    // code owner config metrics
    this.codeOwnerCacheReadsPerChange =
        createHistogram(
            "code_owner_cache_reads_per_change", "Number of code owner cache reads per change");
    this.codeOwnerConfigBackendReadsPerChange =
        createHistogram(
            "code_owner_config_backend_reads_per_change",
            "Number of code owner config backend reads per change");
    this.codeOwnerConfigCacheReadsPerChange =
        createHistogram(
            "code_owner_config_cache_reads_per_change",
            "Number of code owner config cache reads per change");
    this.codeOwnerResolutionsPerChange =
        createHistogram(
            "code_owner_resolutions_per_change", "Number of code owner resolutions per change");
    this.loadCodeOwnerConfig =
        createTimerWithClassField(
            "load_code_owner_config",
            "Latency for loading a code owner config file (read + parse)",
            "backend");
    this.parseCodeOwnerConfig =
        createTimerWithClassField(
            "parse_code_owner_config", "Latency for parsing a code owner config file", "parser");
    this.readCodeOwnerConfig =
        createTimer("read_code_owner_config", "Latency for reading a code owner config file");

    // counter metrics
    this.countCodeOwnerCacheReads =
        createCounter(
            "count_code_owner_cache_reads", "Total number of code owner reads from cache");
    this.countCodeOwnerConfigReads =
        createCounter(
            "count_code_owner_config_reads",
            "Total number of code owner config reads from backend");
    this.countCodeOwnerConfigCacheReads =
        createCounter(
            "count_code_owner_config_cache_reads",
            "Total number of code owner config reads from cache");
    this.countCodeOwnerConfigValidations =
        createCounter3(
            "count_code_owner_config_validations",
            "Total number of code owner config file validations",
            Field.ofEnum(
                    ValidationTrigger.class, "trigger", (metadataBuilder, resolveAllUsers) -> {})
                .description("The trigger of the validation.")
                .build(),
            Field.ofEnum(ValidationResult.class, "result", (metadataBuilder, resolveAllUsers) -> {})
                .description("The result of the validation.")
                .build(),
            Field.ofBoolean("dry_run", (metadataBuilder, resolveAllUsers) -> {})
                .description("Whether the validation was a dry run.")
                .build());
    this.countCodeOwnerResolutions =
        createCounter("count_code_owner_resolutions", "Total number of code owner resolutions");
    this.countCodeOwnerSubmitRuleErrors =
        createCounter1(
            "count_code_owner_submit_rule_errors",
            "Total number of code owner submit rule errors",
            Field.ofString("cause", Metadata.Builder::cause)
                .description("The cause of the submit rule error.")
                .build());
    this.countCodeOwnerSubmitRuleRuns =
        createCounter(
            "count_code_owner_submit_rule_runs", "Total number of code owner submit rule runs");
    this.countCodeOwnerSuggestions =
        createCounter1(
            "count_code_owner_suggestions",
            "Total number of code owner suggestions",
            Field.ofBoolean("resolve_all_users", (metadataBuilder, resolveAllUsers) -> {})
                .description(
                    "Whether code ownerships that are assigned to all users are resolved to random"
                        + " users.")
                .build());
    this.countInvalidCodeOwnerConfigFiles =
        createCounter3(
            "count_invalid_code_owner_config_files",
            "Total number of failed requests caused by an invalid / non-parsable code owner config"
                + " file",
            Field.ofString("project", Metadata.Builder::projectName)
                .description(
                    "The name of the project that contains the invalid code owner config file.")
                .build(),
            Field.ofString("branch", Metadata.Builder::branchName)
                .description(
                    "The name of the branch that contains the invalid code owner config file.")
                .build(),
            Field.ofString("path", Metadata.Builder::filePath)
                .description("The path of the invalid code owner config file.")
                .build());
  }

  private Timer0 createTimer(String name, String description) {
    return metricMaker.newTimer(
        name, new Description(description).setCumulative().setUnit(Units.MILLISECONDS));
  }

  private <F1> Timer1<F1> createTimer(String name, String description, Field<F1> field) {
    return metricMaker.newTimer(
        name,
        new Description(description).setCumulative().setUnit(Description.Units.MILLISECONDS),
        field);
  }

  private Timer1<String> createTimerWithClassField(
      String name, String description, String fieldName) {
    Field<String> CODE_OWNER_BACKEND_FIELD =
        Field.ofString(
                fieldName, (metadataBuilder, fieldValue) -> metadataBuilder.className(fieldValue))
            .build();
    return createTimer(name, description, CODE_OWNER_BACKEND_FIELD);
  }

  private Counter0 createCounter(String name, String description) {
    return metricMaker.newCounter(name, new Description(description).setRate());
  }

  private <F1> Counter1<F1> createCounter1(String name, String description, Field<F1> field1) {
    return metricMaker.newCounter(name, new Description(description).setRate(), field1);
  }

  private <F1, F2, F3> Counter3<F1, F2, F3> createCounter3(
      String name, String description, Field<F1> field1, Field<F2> field2, Field<F3> field3) {
    return metricMaker.newCounter(
        name, new Description(description).setRate(), field1, field2, field3);
  }

  private Histogram0 createHistogram(String name, String description) {
    return metricMaker.newHistogram(name, new Description(description).setCumulative());
  }
}
