package hudson.plugins.git.browser;

import hudson.Extension;
import hudson.model.Descriptor;
import hudson.plugins.git.GitChangeSet;
import hudson.plugins.git.GitChangeSet.Path;
import hudson.scm.EditType;
import hudson.scm.RepositoryBrowser;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Git Browser for GitLab
 */
public class GitLab extends GitRepositoryBrowser {

    private static final long serialVersionUID = 1L;

    private final double version;

    @DataBoundConstructor
    public GitLab(String repoUrl, String version) {
        super(repoUrl);
        this.version = Double.valueOf(version);
    }

    public double getVersion() {
        return version;
    }

    /**
     * Creates a link to the changeset
     *
     * https://[GitLab URL]/commits/a9182a07750c9a0dfd89a8461adf72ef5ef0885b
     *
     * @return diff link
     * @throws IOException
     */
    @Override
    public URL getChangeSetLink(GitChangeSet changeSet) throws IOException {
        String  commitPrefix;

        return new URL(getUrl(), calculatePrefix() + changeSet.getId().toString());
    }

    /**
     * Creates a link to the commit diff.
     * 
     * https://[GitLab URL]/commits/a9182a07750c9a0dfd89a8461adf72ef5ef0885b#[path to file]
     * 
     * @param path
     * @return diff link
     * @throws IOException
     */
    @Override
    public URL getDiffLink(Path path) throws IOException {
        final GitChangeSet changeSet = path.getChangeSet();
        return new URL(getUrl(), calculatePrefix() + changeSet.getId().toString() + "#" + path.getPath());
    }

    /**
     * Creates a link to the file.
     * https://[GitLab URL]/a9182a07750c9a0dfd89a8461adf72ef5ef0885b/tree/pom.xml
     * 
     * @param path
     * @return file link
     * @throws IOException
     */
    @Override
    public URL getFileLink(Path path) throws IOException {
        if (path.getEditType().equals(EditType.DELETE)) {
            return getDiffLink(path);
        } else {
            if(getVersion() < 5.1) {
                return new URL(getUrl(), path.getChangeSet().getId() + "/tree/" + path.getPath());
            } else {
                return new URL(getUrl(), "blob/" + path.getChangeSet().getId() + "/" + path.getPath());
            }
        }
    }

    @Extension
    public static class GitLabDescriptor extends Descriptor<RepositoryBrowser<?>> {
        public String getDisplayName() {
            return "gitlab";
        }

        @Override
        public GitLab newInstance(StaplerRequest req, JSONObject jsonObject) throws FormException {
            return req.bindJSON(GitLab.class, jsonObject);
        }
    }

    private String calculatePrefix() {
        if(getVersion() < 3) {
            return "commits/";
        } else {
            return "commit/";
        }
    } 

}

@@ -903,32 +903,36 @@
    *%0A     * 
-https://
+v &lt; 3.0: 
 %5BGitLab URL%5D
@@ -944,48 +944,60 @@
 its/
-a9182a07750c9a0dfd89a8461adf72ef5ef0885b
+%5BHash%5D%0A     * else:       %5BGitLab URL%5D/commit/%5BHash%5D
 %0A   
@@ -1329,25 +1329,24 @@
 .%0A     *
- 
 %0A     * 
 https://
@@ -1333,32 +1333,36 @@
    *%0A     * 
-https://
+v &lt; 3.0: 
 %5BGitLab URL%5D
@@ -1374,70 +1374,91 @@
 its/
-a9182a07750c9a0dfd89a8461adf72ef5ef0885b#%5Bpath to file
+%5BHash%5D#%5BFile path%5D%0A     * else:       %5BGitLab URL%5D/commit/%5BHash%5D#%5BFile path
 %5D%0A     *
  %0A  
@@ -1449,25 +1449,24 @@
 path%5D%0A     *
- 
 %0A     * @par
@@ -1834,90 +1834,117 @@
   * 
-https://%5BGitLab URL%5D/a9182a07750c9a0dfd89a8461adf72ef5ef0885b/tree/pom.xml
+v &lt; 5.1: %5BGitLab URL%5D%5BHash%5D/tree/%5BFile path%5D%0A     * else:       %5BGitLab URL%5Dblob/%5BHash%5D/%5BFile path%5D
 %0A     *
- 
 %0A   

update documentation