// 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.testing;

import static com.google.common.truth.Fact.simpleFact;
import static com.google.common.truth.Truth.assertAbout;
import static com.google.gerrit.git.testing.ObjectIdSubject.objectIds;
import static com.google.gerrit.truth.OptionalSubject.optionals;

import com.google.common.truth.ComparableSubject;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.IterableSubject;
import com.google.common.truth.StandardSubjectBuilder;
import com.google.common.truth.StringSubject;
import com.google.common.truth.Subject;
import com.google.gerrit.git.testing.ObjectIdSubject;
import com.google.gerrit.plugins.checks.Checker;
import com.google.gerrit.plugins.checks.CheckerUuid;
import com.google.gerrit.plugins.checks.api.CheckerStatus;
import com.google.gerrit.plugins.checks.db.CheckerConfig;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.truth.OptionalSubject;
import java.sql.Timestamp;
import java.util.Optional;
import org.eclipse.jgit.lib.Config;

public class CheckerConfigSubject extends Subject<CheckerConfigSubject, CheckerConfig> {
  public static CheckerConfigSubject assertThat(CheckerConfig checkerConfig) {
    return assertAbout(CheckerConfigSubject::new).that(checkerConfig);
  }

  private CheckerConfigSubject(FailureMetadata metadata, CheckerConfig actual) {
    super(metadata, actual);
  }

  public void hasUuid(CheckerUuid expectedUuid) {
    check("uuid()").that(checker().getUuid()).isEqualTo(expectedUuid);
  }

  public OptionalSubject<StringSubject, String> hasNameThat() {
    return check("name()")
        .about(optionals())
        .that(checker().getName(), StandardSubjectBuilder::that);
  }

  public OptionalSubject<StringSubject, String> hasDescriptionThat() {
    return check("description()")
        .about(optionals())
        .that(checker().getDescription(), StandardSubjectBuilder::that);
  }

  public OptionalSubject<StringSubject, String> hasUrlThat() {
    return check("url()").about(optionals()).that(checker().getUrl(), StandardSubjectBuilder::that);
  }

  public void hasRepository(Project.NameKey expectedRepository) {
    check("repository()").that(checker().getRepository()).isEqualTo(expectedRepository);
  }

  public void hasStatus(CheckerStatus expectedStatus) {
    check("status()").that(checker().getStatus()).isEqualTo(expectedStatus);
  }

  public IterableSubject hasBlockingConditionSetThat() {
    return check("blockingConditions()").that(checker().getBlockingConditions());
  }

  public void hasQuery(String expectedQuery) {
    check("query()").about(optionals()).that(checker().getQuery()).value().isEqualTo(expectedQuery);
  }

  public void hasNoQuery() {
    check("query()").about(optionals()).that(checker().getQuery()).isEmpty();
  }

  public ComparableSubject<?, Timestamp> hasCreatedThat() {
    return check("created()").that(checker().getCreated());
  }

  public ObjectIdSubject hasRefStateThat() {
    return check("refState()").about(objectIds()).that(checker().getRefState());
  }

  public IterableSubject configStringList(String name) {
    isNotNull();
    Optional<Config> checkerConfig = actual().getConfigForTesting();
    check("configValueOf(checker.%s)", name).about(optionals()).that(checkerConfig).isPresent();
    return check("configValueOf(checker.%s)", name)
        .that(checkerConfig.get().getStringList("checker", null, name))
        .asList();
  }

  private Checker checker() {
    isNotNull();
    Optional<Checker> checker = actual().getLoadedChecker();
    if (!checker.isPresent()) {
      failWithActual(simpleFact("expected checker to be loaded"));
    }
    return checker.get();
  }
}
