// Copyright (C) 2016 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.googlesource.gerrit.plugins.automerger;

import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.RevisionResource;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
import java.util.Map;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Implementation behind the "Recreate Automerges" button. */
class AutomergeChangeAction
    implements UiAction<RevisionResource>,
        RestModifyView<RevisionResource, AutomergeChangeAction.Input> {
  private static final Logger log = LoggerFactory.getLogger(AutomergeChangeAction.class);

  private Provider<CurrentUser> user;
  private ConfigLoader config;
  private DownstreamCreator dsCreator;

  @Inject
  AutomergeChangeAction(
      Provider<CurrentUser> user, ConfigLoader config, DownstreamCreator dsCreator) {
    this.user = user;
    this.config = config;
    this.dsCreator = dsCreator;
  }

  /**
   * Gets the input to the button and re-merges downstream based on the input.
   *
   * @param rev RevisionResource of the change whose page we are clicking the button.
   * @param input A map of branch to whether or not the merge should be "-s ours".
   * @return HTTP 200 on success.
   * @throws IOException
   * @throws RestApiException
   * @throws ConfigInvalidException
   * @throws StorageException
   */
  @Override
  public Object apply(RevisionResource rev, Input input)
      throws IOException, RestApiException, StorageException, ConfigInvalidException {
    Map<String, Boolean> branchMap = input.branchMap;

    Change change = rev.getChange();
    if (branchMap == null) {
      log.debug("Branch map is empty for change {}", change.getKey().get());
      return Response.none();
    }
    String revision = rev.getPatchSet().getRevision().get();

    MultipleDownstreamMergeInput mdsMergeInput = new MultipleDownstreamMergeInput();
    mdsMergeInput.dsBranchMap = branchMap;
    mdsMergeInput.changeNumber = change.getId().get();
    mdsMergeInput.patchsetNumber = rev.getPatchSet().getPatchSetId();
    mdsMergeInput.project = change.getProject().get();
    mdsMergeInput.topic = dsCreator.getOrSetTopic(change.getId().get(), change.getTopic());
    mdsMergeInput.subject = change.getSubject();
    mdsMergeInput.obsoleteRevision = revision;
    mdsMergeInput.currentRevision = revision;

    log.debug("Multiple downstream merge input: {}", mdsMergeInput.dsBranchMap);

    try {
      dsCreator.createMergesAndHandleConflicts(mdsMergeInput);
    } catch (ConfigInvalidException e) {
      throw new ResourceConflictException(
          "Automerger configuration file is invalid: " + e.getMessage());
    } catch (InvalidQueryParameterException e) {
      throw new ResourceConflictException(
          "Topic or branch cannot have both braces and quotes: " + e.getMessage());
    }
    return Response.none();
  }

  /**
   * Description for what the DOM element for the button should look like.
   *
   * @param resource RevisionResource of the change whose page the button is on.
   * @return Description object that contains the right labels, visibility, etc.
   */
  @Override
  public Description getDescription(RevisionResource resource) {
    String project = resource.getProject().get();
    String branch = resource.getChange().getDest().shortName();
    Description desc = new Description();
    desc = desc.setLabel("Recreate automerges").setTitle("Recreate automerges downstream");
    try {
      if (config.getDownstreamBranches(branch, project).isEmpty()) {
        desc = desc.setVisible(false);
      } else {
        desc = desc.setVisible(user.get() instanceof IdentifiedUser);
      }
    } catch (RestApiException | IOException | ConfigInvalidException e) {
      log.error("Failed to recreate automerges for {} on {}", project, branch);
      desc = desc.setVisible(false);
    }
    return desc;
  }

  static class Input {
    Map<String, Boolean> branchMap;
  }
}
