package fr.inria.spirals.repairnator;

import fr.inria.spirals.jtravis.entities.Build;
import org.apache.maven.cli.MavenCli;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.RemoteAddCommand;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.transport.URIish;

import java.io.File;

/**
 * Created by urli on 26/12/2016.
 */
public class ProjectInspector {
    public static final String GITHUB_ROOT_REPO = "https://github.com/";

    private Build build;
    private String repoLocalPath;
    private boolean canBeBuilt;
    private boolean canBeCloned;

    public ProjectInspector(Build failingBuild) {
        this.build = failingBuild;
        this.canBeBuilt = false;
        this.canBeCloned = true;
    }

    public boolean canBeBuilt() {
        return this.canBeBuilt;
    }

    public Build getBuild() {
        return this.build;
    }

    public boolean canBeCloned() {
        return this.canBeCloned;
    }

    public void cloneInWorkspace(String workspace) {
        String repository = this.build.getRepository().getSlug();
        this.repoLocalPath = workspace+File.separator+repository;
        String repoRemotePath = GITHUB_ROOT_REPO+repository+".git";

        try {
            Launcher.LOGGER.debug("Cloning repository "+repository+" has in the following directory: "+repoLocalPath);
            Git git = Git.cloneRepository()
                    .setURI(repoRemotePath)
                    .setDirectory(new File(repoLocalPath))
                    .call();

            if (this.build.isPullRequest()) {
                Launcher.LOGGER.debug("Reproduce the PR for "+repository+" by fetching remote branch and merging.");
                String remoteBranchPath = GITHUB_ROOT_REPO+build.getPRRepository().getSlug()+".git";

                RemoteAddCommand remoteBranchCommand = git.remoteAdd();
                remoteBranchCommand.setName("PR");
                remoteBranchCommand.setUri(new URIish(remoteBranchPath));
                remoteBranchCommand.call();

                git.fetch().setRemote("PR").call();

                String commitHeadSha = this.build.getHeadCommit().getSha();
                String commitBaseSha = this.build.getBaseCommit().getSha();

                Ref commitHeadRef = git.getRepository().exactRef(commitHeadSha);
                Ref commitBaseRef = git.getRepository().exactRef(commitBaseSha);

                if (commitHeadRef == null) {
                    Launcher.LOGGER.warn("Commit head ref cannot be retrieved in the repository: "+commitHeadSha);
                    Launcher.LOGGER.debug(this.build.getHeadCommit());
                    this.canBeCloned = false;
                }

                if (commitBaseRef == null) {
                    Launcher.LOGGER.warn("Commit base ref cannot be retrieved in the repository: "+commitBaseSha);
                    Launcher.LOGGER.debug(this.build.getBaseCommit());
                    this.canBeCloned = false;
                }


                Launcher.LOGGER.debug("Get the commit "+commitHeadSha+" for repo "+repository);
                git.checkout().setName(commitHeadSha).call();

                Launcher.LOGGER.debug("Do the merge with the PR commit for repo "+repository);
                git.merge().include(commitBaseRef).call();
            } else {
                String commitCheckout = this.build.getCommit().getSha();

                Launcher.LOGGER.debug("Get the commit "+commitCheckout+" for repo "+repository);
                git.checkout().setName(commitCheckout).call();
            }



        } catch (Exception e) {
            Launcher.LOGGER.warn("Repository "+repository+" cannot be cloned.");
            Launcher.LOGGER.debug(e.toString());
            this.canBeCloned = false;
        }

        MavenCli cli = new MavenCli();

        System.setProperty("maven.test.skip","true");
        int result = cli.doMain(new String[]{"test"},
                repoLocalPath,
                System.out, System.err);

        if (result == 0) {
            this.canBeBuilt = true;
        } else {
            Launcher.LOGGER.info("Repository "+repository+" cannot be built. It will be ignored for the following steps.");
        }
        System.setProperty("maven.test.skip","false");
    }
}

@@ -225,19 +225,182 @@
 git.lib.
-Ref
+AnyObjectId;%0Aimport org.eclipse.jgit.lib.ObjectId;%0Aimport org.eclipse.jgit.lib.Ref;%0Aimport org.eclipse.jgit.revwalk.RevCommit;%0Aimport org.eclipse.jgit.revwalk.RevWalk
 ;%0Aimport
@@ -2370,32 +2370,33 @@
 it().getSha();%0A%0A
+%0A
                 
@@ -2391,27 +2391,32 @@
             
-Ref
+ObjectId
  commitHeadR
@@ -2414,19 +2414,18 @@
 mmitHead
-Ref
+Id
  = git.g
@@ -2435,32 +2435,31 @@
 epository().
-exactRef
+resolve
 (commitHeadS
@@ -2479,19 +2479,24 @@
         
-Ref
+ObjectId
  commitB
@@ -2498,19 +2498,18 @@
 mmitBase
-Ref
+Id
  = git.g
@@ -2527,16 +2527,15 @@
 y().
-exactRef
+resolve
 (com
@@ -2578,19 +2578,18 @@
 mmitHead
-Ref
+Id
  == null
@@ -2696,32 +2696,55 @@
  %22+commitHeadSha
++%22. Operation aborted.%22
 );%0A             
@@ -2839,32 +2839,60 @@
 Cloned = false;%0A
+                    return;%0A
                 
@@ -2924,19 +2924,18 @@
 mmitBase
-Ref
+Id
  == null
@@ -3050,16 +3050,39 @@
 tBaseSha
++%22. Operation aborted.%22
 );%0A     
@@ -3185,32 +3185,60 @@
 Cloned = false;%0A
+                    return;%0A
                 
@@ -3240,17 +3240,16 @@
      %7D%0A%0A
-%0A
         
@@ -3391,32 +3391,179 @@
 adSha).call();%0A%0A
+                RevWalk revwalk = new RevWalk(git.getRepository());%0A                RevCommit revCommitBase = revwalk.lookupCommit(commitBaseId);%0A%0A
                 
@@ -3677,17 +3677,20 @@
 include(
-c
+revC
 ommitBas
@@ -3690,19 +3690,16 @@
 mmitBase
-Ref
 ).call()

Fix the way commit ref were getting from jGit API