/*
 * Copyright 2015 Norbert Potocki (norbert.potocki@nort.pl)
 *
 * 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 org.cfg4j.source.git;

import org.cfg4j.source.files.TempConfigurationFileRepo;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Ref;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

/**
 * Temporary local git repository that contains configuration files.
 */
class TempConfigurationGitRepo extends TempConfigurationFileRepo {

  private final Git repo;

  /**
   * Create temporary, local git repository. When you're done using it remove it by invoking {@link #remove()}
   * method.
   *
   * @throws IOException     when unable to create local directories
   * @throws GitAPIException when unable to execute git operations
   */
  public TempConfigurationGitRepo(String dirName) throws IOException, GitAPIException {
    super(dirName);
    repo = createLocalRepo(dirPath);
  }

  /**
   * Change active branch to {@code branch}. Create the branch if it doesn't exist.
   *
   * @param branch branch to activate
   * @throws GitAPIException when unable to change branch.
   */
  public void changeBranchTo(String branch) throws GitAPIException {
    boolean createBranch = true;

    List<Ref> refList = repo.branchList().call();
    if (anyRefMatches(refList, branch)) {
      createBranch = false;
    }

    repo.checkout()
        .setCreateBranch(createBranch)
        .setName(branch)
        .call();
  }

  /**
   * Change the {@code key} property to {@code value} and store it in a {@code propFilePath} properties file. Commits
   * the change.
   *
   * @param propFilePath relative path to the properties file in this repository
   * @param key          property key
   * @param value        property value
   * @throws IOException     when unable to modify properties file
   * @throws GitAPIException when unable to commit changes
   */
  @Override
  public void changeProperty(Path propFilePath, String key, String value) throws IOException {
    super.changeProperty(propFilePath, key, value);
    try {
      commitChanges();
    } catch (GitAPIException e) {
      throw new IOException(e);
    }
  }

  /**
   * Delete file from this repository. Commits changes.
   *
   * @param filePath relative file path to delete
   * @throws GitAPIException when unable to commit changes
   */
  @Override
  public void deleteFile(Path filePath) throws IOException {
    try {
      super.deleteFile(filePath);

      repo.rm()
          .addFilepattern(filePath.toString())
          .call();

      commitChanges();

    } catch (GitAPIException e) {
      throw new IOException(e);
    }
  }

  /**
   * Remove this repository. Silently fails if repo already removed.
   */
  @Override
  public void remove() {
    try {
      repo.close();
      super.remove();
    } catch (IOException e) {
      // NOP
    }
  }

  private Git createLocalRepo(Path path) throws IOException, GitAPIException {
    System.out.println(path);
    Files.delete(path);

    return Git.init()
        .setDirectory(path.toFile())
        .call();
  }

  private void commitChanges() throws GitAPIException {
    repo.add()
        .addFilepattern(".")
        .call();

    repo.commit()
        .setMessage("config change")
        .call();
  }

  private boolean anyRefMatches(List<Ref> refList, String branch) {
    for (Ref ref : refList) {
      if (ref.getName().replace("refs/heads/", "").equals(branch)) {
        return true;
      }
    }

    return false;
  }
}

@@ -1379,23 +1379,16 @@
    */%0A  
-public 
 TempConf
@@ -1720,23 +1720,16 @@
    */%0A  
-public 
 void cha
@@ -3544,38 +3544,8 @@
 n %7B%0A
-    System.out.println(path);%0A
     

remove debug log statement