/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.apache.ant.vss;

import org.apache.tools.ant.types.EnumeratedAttribute;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.util.FileUtils;

/**
 * A base class for creating tasks for executing commands on Visual SourceSafe.
 * <p>
 * The class extends the 'exec' task as it operates by executing the ss.exe program
 * supplied with SourceSafe. By default the task expects ss.exe to be in the path,
 * you can override this be specifying the ssdir attribute.
 * </p>
 * <p>
 * This class provides set and get methods for 'login' and 'vsspath' attributes. It
 * also contains constants for the flags that can be passed to SS.
 * </p>
 *
 */
public abstract class MSVSS extends Task implements MSVSSConstants {

    private String ssDir = null;
    private String vssLogin = null;
    private String vssPath = null;
    private String serverPath = null;

    /**  Version */
    private String version = null;
    /**  Date */
    private String date = null;
    /**  Label */
    private String label = null;
    /**  Auto response */
    private String autoResponse = null;
    /**  Local path */
    private String localPath = null;
    /**  Comment */
    private String comment = null;
    /**  From label */
    private String fromLabel = null;
    /**  To label */
    private String toLabel = null;
    /**  Output file name */
    private String outputFileName = null;
    /**  User */
    private String user = null;
    /**  From date */
    private String fromDate = null;
    /**  To date */
    private String toDate = null;
    /**  History style */
    private String style = null;
    /**  Quiet defaults to false */
    private boolean quiet = false;
    /**  Recursive defaults to false */
    private boolean recursive = false;
    /**  Writable defaults to false */
    private boolean writable = false;
    /**  Fail on error defaults to true */
    private boolean failOnError = true;
    /**  Get local copy for checkout defaults to true */
    private boolean getLocalCopy = true;
    /**  Number of days offset for History */
    private int numDays = Integer.MIN_VALUE;
    /**  Date format for History */
    private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
    /**  Timestamp for retreived files */
    private CurrentModUpdated timestamp = null;
    /**  Behaviour for writable files */
    private WritableFiles writableFiles = null;
    /**
     * Each sub-class must implemnt this method and return the constructed
     * command line to be executed. It is up to the sub-task to determine the
     * required attrubutes and their order.
     * @return    The Constructed command line.
     */
    abstract Commandline buildCmdLine();

    /**
     * Directory where <code>ss.exe</code> resides.
     * By default the task expects it to be in the PATH.
     * @param  dir  The directory containing ss.exe.
     */
    public final void setSsdir(String dir) {
        this.ssDir = FileUtils.translatePath(dir);
    }

    /**
     * Login to use when accessing VSS, formatted as "username,password".
     * <p>
     * You can omit the password if your database is not password protected.
     * If you have a password and omit it, Ant will hang.
     * @param  vssLogin  The login string to use.
     */
    public final void setLogin(final String vssLogin) {
        this.vssLogin = vssLogin;
    }

    /**
     * SourceSafe path which specifies the project/file(s) you wish to perform
     * the action on.
     * <p>
     * A prefix of 'vss://' will be removed if specified.
     * @param  vssPath  The VSS project path.
     * @ant.attribute group="required"
     */
    public final void setVsspath(final String vssPath) {
        String projectPath;
        if (vssPath.startsWith("vss://")) { //$NON-NLS-1$
            projectPath = vssPath.substring(5);
        } else {
            projectPath = vssPath;
        }

        if (projectPath.startsWith(PROJECT_PREFIX)) {
            this.vssPath = projectPath;
        } else {
            this.vssPath = PROJECT_PREFIX + projectPath;
        }
    }

    /**
     * Directory where <code>srssafe.ini</code> resides.
     * @param  serverPath  The path to the VSS server.
     */
    public final void setServerpath(final String serverPath) {
        this.serverPath = serverPath;
    }

    /**
     * Indicates if the build should fail if the Sourcesafe command does. Defaults to true.
     * @param failOnError True if task should fail on any error.
     */
    public final void setFailOnError(final boolean failOnError) {
        this.failOnError = failOnError;
    }

    /**
     * Executes the task. <br>
     * Builds a command line to execute ss.exe and then calls Exec's run method
     * to execute the command line.
     * @throws BuildException if the command cannot execute.
     */
    public void execute() throws BuildException {
        int result = 0;
        Commandline commandLine = buildCmdLine();
        result = run(commandLine);
        if (Execute.isFailure(result) && getFailOnError()) {
            String msg = "Failed executing: " + formatCommandLine(commandLine)
                     + " With a return code of " + result;
            throw new BuildException(msg, getLocation());
        }
    }

    // Special setters for the sub-classes

    protected void setInternalComment(final String comment) {
        this.comment = comment;
    }

    protected void setInternalAutoResponse(final String autoResponse) {
        this.autoResponse = autoResponse;
    }

    protected void setInternalDate(final String date) {
        this.date = date;
    }

    protected void setInternalDateFormat(final DateFormat dateFormat) {
        this.dateFormat = dateFormat;
    }

    protected void setInternalFailOnError(final boolean failOnError) {
        this.failOnError = failOnError;
    }

    protected void setInternalFromDate(final String fromDate) {
        this.fromDate = fromDate;
    }

    protected void setInternalFromLabel(final String fromLabel) {
        this.fromLabel = fromLabel;
    }

    protected void setInternalLabel(final String label) {
        this.label = label;
    }

    protected void setInternalLocalPath(final String localPath) {
        this.localPath = localPath;
    }

    protected void setInternalNumDays(final int numDays) {
        this.numDays = numDays;
    }

    protected void setInternalOutputFilename(final String outputFileName) {
        this.outputFileName = outputFileName;
    }

    protected void setInternalQuiet(final boolean quiet) {
        this.quiet = quiet;
    }

    protected void setInternalRecursive(final boolean recursive) {
        this.recursive = recursive;
    }

    protected void setInternalStyle(final String style) {
        this.style = style;
    }

    protected void setInternalToDate(final String toDate) {
        this.toDate = toDate;
    }

    protected void setInternalToLabel(final String toLabel) {
        this.toLabel = toLabel;
    }

    protected void setInternalUser(final String user) {
        this.user = user;
    }

    protected void setInternalVersion(final String version) {
        this.version = version;
    }

    protected void setInternalWritable(final boolean writable) {
        this.writable = writable;
    }

    protected void setInternalFileTimeStamp(final CurrentModUpdated timestamp) {
        this.timestamp = timestamp;
    }

    protected void setInternalWritableFiles(final WritableFiles writableFiles) {
        this.writableFiles = writableFiles;
    }

    protected void setInternalGetLocalCopy(final boolean getLocalCopy) {
        this.getLocalCopy = getLocalCopy;
    }

    /**
     * Gets the sscommand string. "ss" or "c:\path\to\ss"
     * @return    The path to ss.exe or just ss if sscommand is not set.
     */
    protected String getSSCommand() {
        if (ssDir == null) {
            return SS_EXE;
        }
        return ssDir.endsWith(File.separator) ? ssDir + SS_EXE : ssDir
                 + File.separator + SS_EXE;
    }

    /**
     * Gets the vssserverpath string.
     * @return    null if vssserverpath is not set.
     */
    protected String getVsspath() {
        return vssPath;
    }

    /**
     * Gets the quiet string. -O-
     * @return An empty string if quiet is not set or is false.
     */
    protected String getQuiet() {
        return quiet ? FLAG_QUIET : "";
    }

    /**
     * Gets the recursive string. "-R"
     * @return An empty string if recursive is not set or is false.
     */
    protected String getRecursive() {
        return recursive ? FLAG_RECURSION : "";
    }

    /**
     * Gets the writable string. "-W"
     * @return An empty string if writable is not set or is false.
     */
    protected String getWritable() {
        return writable ? FLAG_WRITABLE : "";
    }

    /**
     * Gets the label string. "-Lbuild1"
     * Max label length is 32 chars
     * @return An empty string if label is not set.
     */
    protected String getLabel() {
        String shortLabel = "";
        if (label != null && label.length() > 0) {
                shortLabel = FLAG_LABEL + getShortLabel();
        }
        return shortLabel;
    }
    /**
     * Return at most the 30 first chars of the label,
     * logging a warning message about the truncation
     * @return at most the 30 first chars of the label
     */
    private String getShortLabel() {
        String shortLabel;
        if (label !=  null && label.length() > 31) {
            shortLabel = this.label.substring(0, 30);
            log("Label is longer than 31 characters, truncated to: " + shortLabel,
                Project.MSG_WARN);
        } else {
            shortLabel = label;
        }
        return shortLabel;
    }
    /**
     * Gets the style string. "-Lbuild1"
     * @return An empty string if label is not set.
     */
    protected String getStyle() {
        return style != null ? style : "";
    }

    /**
     * Gets the version string. Returns the first specified of version "-V1.0",
     * date "-Vd01.01.01", label "-Vlbuild1".
     * @return An empty string if a version, date and label are not set.
     */
    protected String getVersionDateLabel() {
        String versionDateLabel = "";
        if (version != null) {
            versionDateLabel = FLAG_VERSION + version;
        } else if (date != null) {
            versionDateLabel = FLAG_VERSION_DATE + date;
        } else {
            // Use getShortLabel() so labels longer then 30 char are truncated
            // and the user is warned
            String shortLabel = getShortLabel();
            if (shortLabel != null && !shortLabel.equals("")) {
                versionDateLabel = FLAG_VERSION_LABEL + shortLabel;
            }
        }
        return versionDateLabel;
    }

    /**
     * Gets the version string.
     * @return An empty string if a version is not set.
     */
    protected String getVersion() {
        return version != null ? FLAG_VERSION + version : "";
    }

    /**
     * Gets the localpath string. "-GLc:\source" <p>
     * The localpath is created if it didn't exist.
     * @return An empty string if localpath is not set.
     */
    protected String getLocalpath() {
        String lclPath = ""; //set to empty str if no local path return
        if (localPath != null) {
            //make sure m_LocalDir exists, create it if it doesn't
            File dir = getProject().resolveFile(localPath);
            if (!dir.exists()) {
                boolean done = dir.mkdirs();
                if (!done) {
                    String msg = "Directory " + localPath + " creation was not "
                            + "successful for an unknown reason";
                    throw new BuildException(msg, getLocation());
                }
                getProject().log("Created dir: " + dir.getAbsolutePath());
            }
            lclPath = FLAG_OVERRIDE_WORKING_DIR + localPath;
        }
        return lclPath;
    }

    /**
     * Gets the comment string. "-Ccomment text"
     * @return A comment of "-" if comment is not set.
     */
    protected String getComment() {
        return comment != null ? FLAG_COMMENT + comment : FLAG_COMMENT + "-";
    }

    /**
     * Gets the auto response string. This can be Y "-I-Y" or N "-I-N".
     * @return The default value "-I-" if autoresponse is not set.
     */
    protected String getAutoresponse() {
        if (autoResponse == null) {
            return FLAG_AUTORESPONSE_DEF;
        } else if (autoResponse.equalsIgnoreCase("Y")) {
            return FLAG_AUTORESPONSE_YES;
        } else if (autoResponse.equalsIgnoreCase("N")) {
            return FLAG_AUTORESPONSE_NO;
        } else {
            return FLAG_AUTORESPONSE_DEF;
        }
    }

    /**
     * Gets the login string. This can be user and password, "-Yuser,password"
     * or just user "-Yuser".
     * @return An empty string if login is not set.
     */
    protected String getLogin() {
        return vssLogin != null ? FLAG_LOGIN + vssLogin : "";
    }

    /**
     * Gets the output file string. "-Ooutput.file"
     * @return An empty string if user is not set.
     */
    protected String getOutput() {
        return outputFileName != null ? FLAG_OUTPUT + outputFileName : "";
    }

    /**
     * Gets the user string. "-Uusername"
     * @return An empty string if user is not set.
     */
    protected String getUser() {
        return user != null ? FLAG_USER + user : "";
    }

    /**
     * Gets the version string. This can be to-from "-VLbuild2~Lbuild1", from
     * "~Lbuild1" or to "-VLbuild2".
     * @return An empty string if neither tolabel or fromlabel are set.
     */
    protected String getVersionLabel() {
        if (fromLabel == null && toLabel == null) {
            return "";
        }
        if (fromLabel != null && toLabel != null) {
            if (fromLabel.length() > 31) {
                fromLabel = fromLabel.substring(0, 30);
                log("FromLabel is longer than 31 characters, truncated to: "
                    + fromLabel, Project.MSG_WARN);
            }
            if (toLabel.length() > 31) {
                toLabel = toLabel.substring(0, 30);
                log("ToLabel is longer than 31 characters, truncated to: "
                    + toLabel, Project.MSG_WARN);
            }
            return FLAG_VERSION_LABEL + toLabel + VALUE_FROMLABEL + fromLabel;
        } else if (fromLabel != null) {
            if (fromLabel.length() > 31) {
                fromLabel = fromLabel.substring(0, 30);
                log("FromLabel is longer than 31 characters, truncated to: "
                    + fromLabel, Project.MSG_WARN);
            }
            return FLAG_VERSION + VALUE_FROMLABEL + fromLabel;
        } else {
            if (toLabel.length() > 31) {
                toLabel = toLabel.substring(0, 30);
                log("ToLabel is longer than 31 characters, truncated to: "
                    + toLabel, Project.MSG_WARN);
            }
            return FLAG_VERSION_LABEL + toLabel;
        }
    }

    /**
     * Gets the Version date string.
     * @return An empty string if neither Todate or from date are set.
     * @throws BuildException
     */
    protected String getVersionDate() throws BuildException {
        if (fromDate == null && toDate == null
            && numDays == Integer.MIN_VALUE) {
            return "";
        }
        if (fromDate != null && toDate != null) {
            return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE + fromDate;
        } else if (toDate != null && numDays != Integer.MIN_VALUE) {
            try {
                return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE
                        + calcDate(toDate, numDays);
            } catch (ParseException ex) {
                String msg = "Error parsing date: " + toDate;
                throw new BuildException(msg, getLocation());
            }
        } else if (fromDate != null && numDays != Integer.MIN_VALUE) {
            try {
                return FLAG_VERSION_DATE + calcDate(fromDate, numDays)
                        + VALUE_FROMDATE + fromDate;
            } catch (ParseException ex) {
                String msg = "Error parsing date: " + fromDate;
                throw new BuildException(msg, getLocation());
            }
        } else {
            return fromDate != null ? FLAG_VERSION + VALUE_FROMDATE
                    + fromDate : FLAG_VERSION_DATE + toDate;
        }
    }

    /**
     * Builds and returns the -G- flag if required.
     * @return An empty string if get local copy is true.
     */
    protected String getGetLocalCopy() {
        return (!getLocalCopy) ? FLAG_NO_GET : "";
    }

    /**
     * Gets the value of the fail on error flag.
     * @return    True if the FailOnError flag has been set or if 'writablefiles=skip'.
     */
    private boolean getFailOnError() {
        return getWritableFiles().equals(WRITABLE_SKIP) ? false : failOnError;
    }


    /**
     * Gets the value set for the FileTimeStamp.
     * if it equals "current" then we return -GTC
     * if it equals "modified" then we return -GTM
     * if it equals "updated" then we return -GTU
     * otherwise we return -GTC
     *
     * @return The default file time flag, if not set.
     */
    public String getFileTimeStamp() {
        if (timestamp == null) {
            return "";
        } else if (timestamp.getValue().equals(TIME_MODIFIED)) {
            return FLAG_FILETIME_MODIFIED;
        } else if (timestamp.getValue().equals(TIME_UPDATED)) {
            return FLAG_FILETIME_UPDATED;
        } else {
            return FLAG_FILETIME_DEF;
        }
    }


    /**
     * Gets the value to determine the behaviour when encountering writable files.
     * @return An empty String, if not set.
     */
    public String getWritableFiles() {
        if (writableFiles == null) {
            return "";
        } else if (writableFiles.getValue().equals(WRITABLE_REPLACE)) {
            return FLAG_REPLACE_WRITABLE;
        } else if (writableFiles.getValue().equals(WRITABLE_SKIP)) {
            // ss.exe exits with '100', when files have been skipped
            // so we have to ignore the failure
            failOnError = false;
            return FLAG_SKIP_WRITABLE;
        } else {
            return "";
        }
    }

    /**
     *  Sets up the required environment and executes the command line.
     *
     * @param  cmd  The command line to execute.
     * @return      The return code from the exec'd process.
     */
    private int run(Commandline cmd) {
        try {
            Execute exe = new Execute(new LogStreamHandler(this,
                    Project.MSG_INFO,
                    Project.MSG_WARN));

            // If location of ss.ini is specified we need to set the
            // environment-variable SSDIR to this value
            if (serverPath != null) {
                String[] env = exe.getEnvironment();
                if (env == null) {
                    env = new String[0];
                }
                String[] newEnv = new String[env.length + 1];
                for (int i = 0; i < env.length; i++) {
                    newEnv[i] = env[i];
                }
                newEnv[env.length] = "SSDIR=" + serverPath;

                exe.setEnvironment(newEnv);
            }

            exe.setAntRun(getProject());
            exe.setWorkingDirectory(getProject().getBaseDir());
            exe.setCommandline(cmd.getCommandline());
            // Use the OS launcher so we get environment variables
            exe.setVMLauncher(false);
            return exe.execute();
        } catch (IOException e) {
            throw new BuildException(e, getLocation());
        }
    }

     /**
     * Calculates the start date for version comparison.
     * <p>
     * Calculates the date numDay days earlier than startdate.
     * @param   startDate    The start date.
     * @param   daysToAdd     The number of days to add.
     * @return The calculated date.
     * @throws ParseException
     */
    private String calcDate(String startDate, int daysToAdd) throws ParseException {
        Date currentDate = new Date();
        Calendar calendar = new GregorianCalendar();
        currentDate = dateFormat.parse(startDate);
        calendar.setTime(currentDate);
        calendar.add(Calendar.DATE, daysToAdd);
        return dateFormat.format(calendar.getTime());
    }

    /**
     * Changes the password to '***' so it isn't displayed on screen if the build fails
     *
     * @param cmd   The command line to clean
     * @return The command line as a string with out the password
     */
    private String formatCommandLine(Commandline cmd) {
        StringBuffer sBuff = new StringBuffer(cmd.toString());
        int indexUser = sBuff.substring(0).indexOf(FLAG_LOGIN);
        if (indexUser > 0) {
            int indexPass = sBuff.substring(0).indexOf(",", indexUser);
            int indexAfterPass = sBuff.substring(0).indexOf(" ", indexPass);

            for (int i = indexPass + 1; i < indexAfterPass; i++) {
                sBuff.setCharAt(i, '*');
            }
        }
        return sBuff.toString();
    }

    /**
     * Extention of EnumeratedAttribute to hold the values for file time stamp.
     */
    public static class CurrentModUpdated extends EnumeratedAttribute {
        /**
         * Gets the list of allowable values.
         * @return The values.
         */
        public String[] getValues() {
            return new String[] {TIME_CURRENT, TIME_MODIFIED, TIME_UPDATED};
        }
    }

    /**
     * Extention of EnumeratedAttribute to hold the values for writable filess.
     */
    public static class WritableFiles extends EnumeratedAttribute {
        /**
         * Gets the list of allowable values.
         * @return The values.
         */
        public String[] getValues() {
            return new String[] {WRITABLE_REPLACE, WRITABLE_SKIP, WRITABLE_FAIL};
        }
    }
}
