/*
 * Copyright 2008 Google Inc.
 * 
 * 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 com.google.gwt.ant.taskdefs;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

import java.io.File;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A Svn interface task, because the initial solution of <exec> and
 * <propertyregex> is unhappy in ant 1.6.5, and while that's old, it's not quite
 * "too old" for us to care.
 */
public class SvnInfo extends Task {

  /**
   * Structured svn info.
   */
  static class Info {
    /**
     * The relative path of this svn working copy within the root of the remote
     * repository. That is, if the root is "http://example.com/svn" and the
     * working copy URL is "http://example.com/svn/tags/w00t", this will be set
     * to "tags/w00t".
     */
    public final String branch;

    /**
     * The revision of this working copy. Initially set to the value parsed from
     * "svn info" given a more detailed value via "svnversion".
     */
    public String revision;

    public Info(String branch, String revision) {
      this.branch = branch;
      this.revision = revision;
    }
  }

  /**
   * A regex that matches a URL.
   */
  static final String URL_REGEX = "\\w+://\\S*";

  /**
   * A pattern that matches the URL line in svn info output.  Note that it
   * <i>also</i> matches Repository Root; to support i18n subversion clients,
   * we're positionally dependent that URL will be the first match, and
   * Repository Root the second.
   */
  private static final Pattern BRANCH_PATTERN = Pattern.compile("[^:]*:\\s*("
      + URL_REGEX + ")\\s*");

  /**
   * A pattern that matches the Revision line in svn info output.  <i>Also</i>
   * matches Last Changed Rev; we're positionally dependent (revision is
   * earlier) to support internationalized svn client output.
   */
  private static final Pattern REVISION_PATTERN = Pattern.compile("[^:]*:\\s*(\\d+)\\s*");

  /**
   * A pattern that matches the Repository Root line in svn info output.
   */
  private static final Pattern ROOT_PATTERN = Pattern.compile("[^:]*:\\s*("
      + URL_REGEX + "/svn)\\s*");

  /**
   * Returns true if this git working copy matches the specified svn revision,
   * and also has no local modifications.
   */
  static boolean doesGitWorkingCopyMatchSvnRevision(File dir, String svnRevision) {
    String workingRev = getGitWorkingRev(dir);
    String targetRev = getGitRevForSvnRev(dir, svnRevision);
    if (!workingRev.equals(targetRev)) {
      return false;
    }
    String status = getGitStatus(dir);
    return status.contains("nothing to commit (working directory clean)");
  }

  /**
   * Returns the git commit number matching the specified svn revision.
   */
  static String getGitRevForSvnRev(File dir, String svnRevision) {
    String output = CommandRunner.getCommandOutput(dir, "git", "svn",
        "find-rev", "r" + svnRevision);
    output = output.trim();
    if (output.length() == 0) {
      throw new BuildException("git svn find-rev didn't give any answer");
    }
    return output;
  }

  /**
   * Runs "git status" and returns the result.
   */
  static String getGitStatus(File dir) {
    // git status returns 1 for a status code, so just don't check it.
    String output = CommandRunner.getCommandOutput(false, dir, "git", "status");
    if (output.length() == 0) {
      throw new BuildException("git status didn't give any answer");
    }
    return output;
  }

  /**
   * Runs "git svn info", returning the output as a string.
   */
  static String getGitSvnInfo(File dir) {
    String output = CommandRunner.getCommandOutput(dir, "git", "svn", "info");
    if (output.length() == 0) {
      throw new BuildException("git svn info didn't give any answer");
    }
    return output;
  }

  /**
   * Returns the current git commit number of the working copy.
   */
  static String getGitWorkingRev(File dir) {
    String output = CommandRunner.getCommandOutput(dir, "git", "rev-list",
        "--max-count=1", "HEAD");
    output = output.trim();
    if (output.length() == 0) {
      throw new BuildException("git rev-list didn't give any answer");
    }
    return output;
  }

  /**
   * Runs "svn info", returning the output as a string.
   */
  static String getSvnInfo(File dir) {
    String output = CommandRunner.getCommandOutput(dir, "svn", "info");
    if (output.length() == 0) {
      throw new BuildException("svn info didn't give any answer");
    }
    return output;
  }

  /**
   * Runs "svnversion", returning the output as a string.
   */
  static String getSvnVersion(File dir) {
    String output = CommandRunner.getCommandOutput(dir, "svnversion", ".");
    output = output.trim();
    if (output.length() == 0) {
      throw new BuildException("svnversion didn't give any answer");
    }
    return output;
  }

  /**
   * Determine if this directory is a part of a .git repository.
   * 
   * @param dir working directory to start looking for the repository.
   * @return <code>true</code> if a .git repo is found. Returns
   *         <code>false</false> if a .git repo cannot be found, or if 
   *         this directory is part of a subversion repository.
   */
  static boolean looksLikeGit(File dir) {
    if (looksLikeSvn(dir)) {
      return false;
    }
    File gitDir = findGitDir(dir);

    if (gitDir != null && gitDir.isDirectory()) {
      return new File(gitDir, "svn").isDirectory();
    }
    return false;
  }

  /**
   * Returns <code>true</code> if the specified directory looks like an svn
   * working copy.
   */
  static boolean looksLikeSvn(File dir) {
    return new File(dir, ".svn").isDirectory();
  }

  /**
   * Parses the output of running "svn info".
   */
  static Info parseInfo(String svnInfo) {
    String rootUrl = null;
    String branchUrl = null;
    String revision = null;
    LineNumberReader lnr = new LineNumberReader(new StringReader(svnInfo));
    try {
      for (String line = lnr.readLine(); line != null; line = lnr.readLine()) {
        Matcher m;
        if ((m = ROOT_PATTERN.matcher(line)) != null && m.matches()) {
          rootUrl = m.group(1);
        } else if ((m = BRANCH_PATTERN.matcher(line)) != null && m.matches()) {
          if (branchUrl == null) {
            branchUrl = m.group(1);
          } // else skip the 2nd and later matches
        } else if ((m = REVISION_PATTERN.matcher(line)) != null && m.matches()) {
          if (revision == null) {
            revision = m.group(1);
          } // else skip the 2nd and later matches
        }
      }
    } catch (IOException e) {
      throw new BuildException("Should never happen", e);
    }

    if (rootUrl == null) {
      throw new BuildException("svn info didn't get root URL: " + svnInfo);
    }
    if (branchUrl == null) {
      throw new BuildException("svn info didn't get branch URL: " + svnInfo);
    }
    if (revision == null) {
      throw new BuildException("svn info didn't get revision: " + svnInfo);
    }
    rootUrl = removeTrailingSlash(rootUrl);
    branchUrl = removeTrailingSlash(branchUrl);
    if (!branchUrl.startsWith(rootUrl)) {
      throw new BuildException("branch URL (" + branchUrl + ") and root URL ("
          + rootUrl + ") did not match");
    }

    String branch;
    if (branchUrl.length() == rootUrl.length()) {
      branch = "";
    } else {
      branch = branchUrl.substring(rootUrl.length() + 1);
    }
    return new Info(branch, revision);
  }

  static String removeTrailingSlash(String url) {
    if (url.endsWith("/")) {
      return url.substring(0, url.length() - 1);
    }
    return url;
  }

  /**
   * Find the GIT working directory.
   * 
   * First checks for the presence of the env variable GIT_DIR, then, looks up
   * the tree for a directory named '.git'.
   * 
   * @param dir Current working directory
   * @return An object representing the .git directory. Returns
   *         <code>null</code> if none can be found.
   */
  private static File findGitDir(File dir) {
    String gitDirPath = System.getenv("GIT_DIR");
    if (gitDirPath != null) {
      File gitDir = new File(gitDirPath).getAbsoluteFile();
      if (gitDir.isDirectory()) {
        return gitDir;
      }
    }

    dir = dir.getAbsoluteFile();
    while (dir != null) {
      File gitDir = new File(dir, ".git"); 
      if (gitDir.isDirectory()) {
        return gitDir;
      }
      dir = dir.getParentFile();
    }
    return null;
  }

  private String fileprop;

  private String outprop;

  private String workdir;

  public SvnInfo() {
    super();
  }

  @Override
  public void execute() throws BuildException {
    if (outprop == null) {
      throw new BuildException(
          "<svninfo> task requires an outputproperty attribute");
    }
    if (workdir == null) {
      workdir = getProject().getProperty("basedir");
    }
    File workDirFile = new File(workdir);
    if (!workDirFile.isDirectory()) {
      throw new BuildException(workdir + " is not a directory");
    }

    if (getProject().getProperty(outprop) == null) {
      Info info;
      if (looksLikeSvn(workDirFile)) {
        info = parseInfo(getSvnInfo(workDirFile));
  
        // Use svnversion to get a more exact revision string.
        info.revision = getSvnVersion(workDirFile);
      } else if (looksLikeGit(workDirFile)) {
        info = parseInfo(getGitSvnInfo(workDirFile));
  
        // Add a 'M' tag if this working copy is not pristine.
        if (!doesGitWorkingCopyMatchSvnRevision(workDirFile, info.revision)) {
          info.revision += "M";
        }
      } else {
        info = new Info("unknown", "unknown");
      }
      getProject().setNewProperty(outprop, info.branch + "@" + info.revision);
    } else {
      String propval = getProject().getProperty(outprop);
      if (!propval.matches("[^@]+@[0-9]+")) {
        throw new BuildException(
          "predefined " + outprop +
              "should look like branch-spec@revison-number");
      }
    }
    if (fileprop != null) {
      String outpropval = getProject().getProperty(outprop);
      int atIndex = outpropval.indexOf('@');
      String branch = outpropval.substring(0, atIndex);
      String revision = outpropval.substring(atIndex + 1);
      
      getProject().setNewProperty(fileprop,
          branch.replace('/', '-') + "-" + revision.replace(':', '-'));
    }
  }

  /**
   * Establishes the directory used as the SVN workspace to fetch version
   * information.
   * 
   * @param srcdir workspace directory name
   */
  public void setDirectory(String srcdir) {
    workdir = srcdir;
  }

  /**
   * Establishes the property containing the SVN output string, branch@rev.
   * 
   * @param propname Name of a property
   */
  public void setOutputFileProperty(String propname) {
    fileprop = propname;
  }

  /**
   * Establishes the property containing the SVN output string, branch@rev.
   * 
   * @param propname Name of a property
   */
  public void setOutputProperty(String propname) {
    outprop = propname;
  }
}
