// 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 Timer0 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");
    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());
  }
}
