/*
 * MIT License
 *
 * Copyright (c) 2020-present Cloudogu GmbH and Contributors
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package sonia.scm.repository.api;

import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.event.ScmEventBus;
import sonia.scm.repository.Branch;
import sonia.scm.repository.BranchCreatedEvent;
import sonia.scm.repository.Repository;
import sonia.scm.repository.spi.BranchCommand;

/**
 * @since 2.0
 */
public final class BranchCommandBuilder {

  private static final Logger LOG = LoggerFactory.getLogger(BranchCommandBuilder.class);

  private final Repository repository;
  private final BranchCommand command;
  private final ScmEventBus eventBus;
  private final BranchRequest request = new BranchRequest();

  public BranchCommandBuilder(Repository repository, BranchCommand command) {
    this(repository, command, ScmEventBus.getInstance());
  }

  /**
   * Creates a new {@link BranchCommandBuilder}.
   *
   * @param command type specific command implementation
   *
   * @deprecated use {@link #BranchCommandBuilder(Repository, BranchCommand)} instead.
   */
  @Deprecated
  public BranchCommandBuilder(BranchCommand command) {
    this(null, command, ScmEventBus.getInstance());
  }

  @VisibleForTesting
  BranchCommandBuilder(Repository repository, BranchCommand command, ScmEventBus eventBus) {
    this.repository = repository;
    this.command = command;
    this.eventBus = eventBus;
  }

  /**
   * Specifies the source branch, which the new branch should be based on.
   *
   * @param parentBranch The base branch for the new branch.
   * @return This builder.
   */
  public BranchCommandBuilder from(String parentBranch) {
    request.setParentBranch(parentBranch);
    return this;
  }

  /**
   * Execute the command and create a new branch with the given name.
   * @param name The name of the new branch.
   * @return The created branch.
   */
  public Branch branch(String name) {
    request.setNewBranch(name);
    Branch branch = command.branch(request);
    fireCreatedEvent(branch);
    return branch;
  }

  private void fireCreatedEvent(Branch branch) {
    if (repository != null) {
      eventBus.post(new BranchCreatedEvent(repository, branch.getName()));
    } else {
      LOG.warn("the branch command was created without a repository, so we are not able to fire a BranchCreatedEvent");
    }
  }

  public void delete(String branchName) {
    command.deleteOrClose(branchName);
  }
}
