/*
 * 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 pl.nort.config.source;

import static org.assertj.core.api.Assertions.assertThat;

import org.assertj.core.data.MapEntry;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;

public class GitConfigurationSourceIntegrationTest {

  @Rule
  public ExpectedException expectedException = ExpectedException.none();

  private SampleGitRepo remoteRepo;

  @Before
  public void setUp() throws Exception {
    remoteRepo = new SampleGitRepo();
    remoteRepo.changeProperty("application.properties", "some.setting", "value");
  }

  @After
  public void tearDown() throws Exception {
    remoteRepo.close();
  }

  @Test
  public void shouldThrowWhenUnableToCreateLocalCloneOnNoTempDir() throws Exception {
    expectedException.expect(GitConfigurationSourceException.class);
    new GitConfigurationSource(remoteRepo.getURI(), "/someNonexistentDir/lkfjalfcz", "existing-path");
  }

  @Test
  public void shouldThrowOnInvalidRemote() throws Exception {
    expectedException.expect(GitConfigurationSourceException.class);
    new GitConfigurationSource(File.createTempFile("temp", "temp").getAbsolutePath());
  }

  @Test
  public void shouldReadConfigFromRemoteRepository() throws Exception {
    try (GitConfigurationSource gitConfigurationSource = new GitConfigurationSource(remoteRepo.getURI())) {
      assertThat(gitConfigurationSource.getConfiguration()).contains(MapEntry.entry("some.setting", "value"));
    }
  }

  private static class SampleGitRepo {

    private final Git repo;

    public SampleGitRepo() throws IOException, GitAPIException {
      File tempFile = File.createTempFile("test-repo.git", "");
      repo = createLocalRepo(tempFile);
    }

    public String getURI() {
      return repo.getRepository().getWorkTree().getAbsolutePath();
    }

    public void changeProperty(String propFilePath, String key, String value) throws IOException, GitAPIException {
      writePropertyToFile(propFilePath, key, value);
      commitChangesTo(repo);
    }

    private Git createLocalRepo(File path) throws IOException, GitAPIException {
      path.delete();
      return Git.init()
          .setDirectory(path)
          .call();
    }

    private void writePropertyToFile(String propFilePath, String key, String value) throws IOException {
      OutputStream out = new FileOutputStream(getURI() + "/" + propFilePath);
      Properties properties = new Properties();
      properties.put(key, value);
      properties.store(out, "");
      out.close();
    }

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

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

    public void close() {
      repo.close();
    }
  }

}
@@ -1521,28 +1521,29 @@
  remoteRepo.
-clos
+remov
 e();%0A  %7D%0A%0A  
@@ -2351,17 +2351,19 @@
   %7D%0A  %7D%0A
+  
 %0A
-
   privat
@@ -2899,32 +2899,123 @@
 o(repo);%0A    %7D%0A%0A
+    public void remove() %7B%0A      repo.close();%0A      deleteDir(new File(getURI()));%0A    %7D%0A%0A
     private Git 
@@ -3741,22 +3741,148 @@
 ic void 
-close(
+deleteDir(File directory) %7B%0A      if (directory.exists()) %7B%0A        File%5B%5D files = directory.listFiles();%0A%0A        if (files != null
 ) %7B%0A    
@@ -3879,37 +3879,244 @@
 ll) %7B%0A      
+  
-repo.close();
+  for (File file : files) %7B%0A            if (file.isDirectory()) %7B%0A              deleteDir(file);%0A            %7D else %7B%0A              file.delete();%0A            %7D%0A          %7D%0A        %7D%0A        directory.delete();%0A      %7D
 %0A    %7D%0A  %7D%0A%0A

remove test repo after test