// 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.acceptance.testsuite;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.plugins.checks.Check;
import com.google.gerrit.plugins.checks.CheckJson;
import com.google.gerrit.plugins.checks.CheckKey;
import com.google.gerrit.plugins.checks.CheckUpdate;
import com.google.gerrit.plugins.checks.CheckerRef;
import com.google.gerrit.plugins.checks.Checks;
import com.google.gerrit.plugins.checks.Checks.GetCheckOptions;
import com.google.gerrit.plugins.checks.ChecksUpdate;
import com.google.gerrit.plugins.checks.ListChecksOption;
import com.google.gerrit.plugins.checks.api.CheckInfo;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.Note;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevWalk;

public final class CheckOperationsImpl implements CheckOperations {
  private final Checks checks;
  private final Provider<ChecksUpdate> checksUpdate;
  private final CheckJson.Factory checkJsonFactory;
  private final GitRepositoryManager repoManager;

  @Inject
  public CheckOperationsImpl(
      Checks checks,
      GitRepositoryManager repoManager,
      CheckJson.Factory checkJsonFactory,
      @ServerInitiated Provider<ChecksUpdate> checksUpdate) {
    this.checks = checks;
    this.repoManager = repoManager;
    this.checkJsonFactory = checkJsonFactory;
    this.checksUpdate = checksUpdate;
  }

  @Override
  public PerCheckOperations check(CheckKey key) {
    return new PerCheckOperationsImpl(key);
  }

  @Override
  public TestCheckUpdate.Builder newCheck(CheckKey key) {
    return TestCheckUpdate.builder(key)
        .checkUpdater(u -> checksUpdate.get().createCheck(key, toCheckUpdate(u)));
  }

  final class PerCheckOperationsImpl implements PerCheckOperations {
    private final CheckKey key;

    PerCheckOperationsImpl(CheckKey key) {
      this.key = key;
    }

    @Override
    public boolean exists() throws Exception {
      return checks.getCheck(key, GetCheckOptions.defaults()).isPresent();
    }

    @Override
    public Check get() throws Exception {
      return checks
          .getCheck(key, GetCheckOptions.defaults())
          .orElseThrow(() -> new IllegalStateException("Tried to get non-existing test check"));
    }

    @Override
    public ImmutableMap<ObjectId, String> notesAsText() throws Exception {
      try (Repository repo = repoManager.openRepository(key.repository());
          RevWalk rw = new RevWalk(repo)) {
        Ref checkRef =
            repo.getRefDatabase().exactRef(CheckerRef.checksRef(key.patchSet().changeId()));
        checkNotNull(checkRef);

        NoteMap notes = NoteMap.read(rw.getObjectReader(), rw.parseCommit(checkRef.getObjectId()));
        ImmutableMap.Builder<ObjectId, String> raw = ImmutableMap.builder();

        for (Note note : notes) {
          raw.put(
              note.copy(),
              new String(notes.getCachedBytes(note.toObjectId(), Integer.MAX_VALUE), UTF_8));
        }
        return raw.build();
      }
    }

    @Override
    public CheckInfo asInfo(ListChecksOption... options) throws Exception {
      return checkJsonFactory.create(ImmutableSet.copyOf(options)).format(get());
    }

    @Override
    public TestCheckUpdate.Builder forUpdate() {
      return TestCheckUpdate.builder(key)
          .checkUpdater(
              testUpdate -> checksUpdate.get().updateCheck(key, toCheckUpdate(testUpdate)));
    }
  }

  private static CheckUpdate toCheckUpdate(TestCheckUpdate testUpdate) {
    CheckUpdate.Builder update = CheckUpdate.builder();
    testUpdate.message().ifPresent(update::setMessage);
    testUpdate.state().ifPresent(update::setState);
    testUpdate.started().ifPresent(update::setStarted);
    testUpdate.finished().ifPresent(update::setFinished);
    testUpdate.url().ifPresent(update::setUrl);
    return update.build();
  }
}
