/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.StringUtils;

import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * CVSLogin
 *
 * Adds an new entry to a CVS password file
 *
 * @author <a href="jeff@custommonkey.org">Jeff Martin</a>
 * @version $Revision$
 *
 * @since Ant 1.4
 *
 * @ant.task category="scm"
 */
public class CVSPass extends Task {
    /** CVS Root */
    private String cvsRoot = null; 
    /** Password file to add password to */
    private File passFile = null;
    /** Password to add to file */
    private String password = null;

    /** Array contain char conversion data */
    private final char[] shifts = {
          0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
         16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
        114, 120,  53,  79,  96, 109,  72, 108,  70,  64,  76,  67, 116,  74,  68,  87,
        111,  52,  75, 119,  49,  34,  82,  81,  95,  65, 112,  86, 118, 110, 122, 105,
         41,  57,  83,  43,  46, 102,  40,  89,  38, 103,  45,  50,  42, 123,  91,  35,
        125,  55,  54,  66, 124, 126,  59,  47,  92,  71, 115,  78,  88, 107, 106,  56,
         36, 121, 117, 104, 101, 100,  69,  73,  99,  63,  94,  93,  39,  37,  61,  48,
         58, 113,  32,  90,  44,  98,  60,  51,  33,  97,  62,  77,  84,  80,  85, 223,
        225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190,
        199, 170, 181, 204, 138, 232, 218, 183, 255, 234, 220, 247, 213, 203, 226, 193,
        174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 161, 179, 160, 212,
        207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246,
        192, 159, 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176,
        227, 231, 219, 169, 175, 156, 206, 198, 129, 164, 150, 210, 154, 177, 134, 127,
        182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 171, 195,
        243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152 
    };

    /**
     * Create a CVS task using the default cvspass file location.
     */
    public CVSPass(){
        passFile = new File(System.getProperty("user.home") + "/.cvspass");
    }

    /**
     * Does the work.
     *
     * @exception BuildException if someting goes wrong with the build
     */
    public final void execute() throws BuildException {
        if (cvsRoot == null) {
            throw new BuildException("cvsroot is required");
        }
        if (password == null) {
            throw new BuildException("password is required");
        }

        log("cvsRoot: " + cvsRoot, Project.MSG_DEBUG);
        log("password: " + password, Project.MSG_DEBUG);
        log("passFile: " + passFile, Project.MSG_DEBUG);

        BufferedReader reader = null;
        PrintWriter writer = null;
        try {
            StringBuffer buf = new StringBuffer();

            if (passFile.exists()) {
                reader = new BufferedReader(new FileReader(passFile));

                String line = null;

                while ((line = reader.readLine()) != null) {
                    if (!line.startsWith(cvsRoot)) {
                        buf.append(line).append(StringUtils.LINE_SEP);
                    }
                }
            }

            String pwdfile = buf.toString() + cvsRoot + " A" 
                + mangle(password);

            log("Writing -> " + pwdfile , Project.MSG_DEBUG);

            writer = new PrintWriter(new FileWriter(passFile));

            writer.println(pwdfile);
        } catch (IOException e) {
            throw new BuildException(e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {}
            }
            if (writer != null) {
                writer.close();
            }
        }
    }

    private final String mangle(String password){
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < password.length(); i++) {
            buf.append(shifts[password.charAt(i)]);
        }
        return buf.toString();
    }

    /**
     * Sets cvs root to be added to the password file
     */
    public void setCvsroot(String cvsRoot) {
        this.cvsRoot = cvsRoot;
    }

    /**
     * Sets the password file attribute.
     */
    public void setPassfile(File passFile) {
        this.passFile = passFile;
    }

    /**
     * Sets the password attribute.
     */
    public void setPassword(String password) {
        this.password = password;
    }

}
