// 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 addChangeMessageOnCodeOwnerApproval;
  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.addChangeMessageOnCodeOwnerApproval =
        createTimer(
            "add_change_message_on_code_owner_approval",
            "Latency for asynchronously adding a change message with the owned path when a code"
                + " owner approval is applied");
    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 synchronously 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());
  }
}
