// Copyright (C) 2019 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.checks;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.plugins.checks.api.BlockingCondition;
import com.google.gerrit.plugins.checks.api.CheckerStatus;
import java.sql.Timestamp;
import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;

/** Definition of a checker. */
@AutoValue
public abstract class Checker {
  /**
   * Returns the UUID of the checker.
   *
   * <p>The UUID is unique across all checkers.
   *
   * @return UUID
   */
  public abstract CheckerUuid getUuid();

  /**
   * Returns the display name of the checker.
   *
   * <p>The same name may be used by multiple checkers.
   *
   * @return display name of the checker
   */
  public abstract String getName();

  /**
   * Returns the description of the checker.
   *
   * <p>Checkers may not have a description, in this case {@link Optional#empty()} is returned.
   *
   * @return the description of the checker
   */
  public abstract Optional<String> getDescription();

  /**
   * Returns the URL of the checker.
   *
   * <p>Checkers may not have a URL, in this case {@link Optional#empty()} is returned.
   *
   * @return the URL of the checker
   */
  public abstract Optional<String> getUrl();

  /**
   * Returns the repository to which the checker applies.
   *
   * <p>The repository is the exact name of a repository (no prefix, no regexp).
   *
   * @return the repository to which the checker applies
   */
  public abstract Project.NameKey getRepository();

  /**
   * Returns the status of the checker.
   *
   * @return the status of the checker.
   */
  public abstract CheckerStatus getStatus();

  /**
   * Returns the blocking conditions for the checker.
   *
   * @return the blocking conditions for the checker.
   */
  public abstract ImmutableSortedSet<BlockingCondition> getBlockingConditions();

  /**
   * Returns the query for the checker.
   *
   * <p>If set, represents a limited change query that all relevant changes will match.
   *
   * @return the query for the checker.
   */
  public abstract Optional<String> getQuery();

  /**
   * Returns the creation timestamp of the checker.
   *
   * @return the creation timestamp
   */
  public abstract Timestamp getCreated();

  /**
   * Returns the timestamp of when the checker was last updated.
   *
   * @return the last updated timestamp
   */
  public abstract Timestamp getUpdated();

  /**
   * Returns the ref state of the checker.
   *
   * @return the ref state
   */
  public abstract ObjectId getRefState();

  public abstract Builder toBuilder();

  public static Builder builder() {
    return new AutoValue_Checker.Builder();
  }

  public boolean isDisabled() {
    return CheckerStatus.DISABLED == getStatus();
  }

  /**
   * Checks whether a {@link Checker} is required for submission or not.
   *
   * @return true if the {@link Checker} required for submission.
   */
  public boolean isRequired() {
    ImmutableSet<BlockingCondition> blockingConditions = getBlockingConditions();
    if (blockingConditions.isEmpty()) {
      return false;
    } else if (blockingConditions.size() > 1
        || !blockingConditions.contains(BlockingCondition.STATE_NOT_PASSING)) {
      // When a new blocking condition is introduced, this needs to be adjusted to respect that.
      String errorMessage = String.format("illegal blocking conditions %s", blockingConditions);
      throw new IllegalStateException(errorMessage);
    }
    return true;
  }

  /** A builder for an {@link Checker}. */
  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder setUuid(CheckerUuid uuid);

    public abstract CheckerUuid getUuid();

    public abstract Builder setName(String name);

    public abstract Builder setDescription(String description);

    public abstract Builder setUrl(String url);

    public abstract Builder setRepository(Project.NameKey repository);

    public abstract Builder setStatus(CheckerStatus status);

    public abstract Builder setBlockingConditions(Iterable<BlockingCondition> enumList);

    public abstract Builder setQuery(String query);

    public abstract Builder setCreated(Timestamp created);

    public abstract Builder setUpdated(Timestamp updated);

    public abstract Builder setRefState(ObjectId refState);

    public abstract Checker build();
  }
}
