/*
 * Copyright 2004-2005 The Apache Software Foundation.
 * 
 * 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 org.apache.catalina.storeconfig;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.sql.Timestamp;

/**
 * Move server.xml or context.xml as backup
 * 
 * @author Peter Rossbach
 * 
 * TODO Get Encoding from Registry
 */
public class StoreFileMover {

    private String filename = "conf/server.xml";

    private String encoding = "UTF-8";

    private String basename = System.getProperty("catalina.base");

    private File configOld;

    private File configNew;

    private File configSave;

    /**
     * @return Returns the configNew.
     */
    public File getConfigNew() {
        return configNew;
    }

    /**
     * @return Returns the configOld.
     */
    public File getConfigOld() {
        return configOld;
    }

    /**
     * @return Returns the configSave.
     */
    public File getConfigSave() {
        return configSave;
    }

    /**
     * @return Returns the basename.
     */
    public String getBasename() {
        return basename;
    }

    /**
     * @param basename
     *            The basename to set.
     */
    public void setBasename(String basename) {
        this.basename = basename;
    }

    /**
     * @return The file name
     */
    public String getFilename() {
        return filename;
    }

    /**
     * @param string
     */
    public void setFilename(String string) {
        filename = string;
    }

    /**
     * @return The encoding
     */
    public String getEncoding() {
        return encoding;
    }

    /**
     * @param string
     */
    public void setEncoding(String string) {
        encoding = string;
    }

    /**
     * Calculate file objects for the old and new configuration files.
     */
    public StoreFileMover(String basename, String filename, String encoding) {
        setBasename(basename);
        setEncoding(encoding);
        setFilename(filename);
        init();
    }

    /**
     * Calculate file objects for the old and new configuration files.
     */
    public StoreFileMover() {
        init();
    }

    /**
     * generate the Filename to new with TimeStamp
     */
    public void init() {
        String configFile = getFilename();
        configOld = new File(configFile);
        if (!configOld.isAbsolute()) {
            configOld = new File(getBasename(), configFile);
        }
        configNew = new File(configFile + ".new");
        if (!configNew.isAbsolute()) {
            configNew = new File(getBasename(), configFile + ".new");
        }
        if (!configNew.getParentFile().exists()) {
            configNew.getParentFile().mkdirs();
        }
        String sb = getTimeTag();
        configSave = new File(configFile + sb);
        if (!configSave.isAbsolute()) {
            configSave = new File(getBasename(), configFile + sb);
        }
    }

    /**
     * Shuffle old->save and new->old
     * 
     * @throws IOException
     */
    public void move() throws IOException {
        if (configOld.renameTo(configSave)) {
            if (!configNew.renameTo(configOld)) {
                configSave.renameTo(configOld);
                throw new IOException("Cannot rename "
                        + configNew.getAbsolutePath() + " to "
                        + configOld.getAbsolutePath());
            }
        } else {
            if (!configOld.exists()) {
                if (!configNew.renameTo(configOld)) {
                    throw new IOException("Cannot move "
                            + configNew.getAbsolutePath() + " to "
                            + configOld.getAbsolutePath());
                }
            } else {
                throw new IOException("Cannot rename "
                    + configOld.getAbsolutePath() + " to "
                    + configSave.getAbsolutePath());
            }
        }
    }

    /**
     * Open an output writer for the new configuration file
     * 
     * @return The writer
     * @throws IOException
     */
    public PrintWriter getWriter() throws IOException {
        PrintWriter writer = null;
        try {
            writer = new PrintWriter(new OutputStreamWriter(
                    new FileOutputStream(configNew), getEncoding()));
        } catch (IOException e) {
            if (writer != null) {
                try {
                    writer.close();
                } catch (Throwable t) {
                    ;
                }
            }
            throw (e);
        }
        return writer;
    }

    /**
     * Time value for backup yyyy-mm-dd.hh-mm-ss
     * 
     * @return The time
     */
    protected String getTimeTag() {
        String ts = (new Timestamp(System.currentTimeMillis())).toString();
        //        yyyy-mm-dd hh:mm:ss
        //        0123456789012345678
        StringBuffer sb = new StringBuffer(".");
        sb.append(ts.substring(0, 10));
        sb.append('.');
        sb.append(ts.substring(11, 13));
        sb.append('-');
        sb.append(ts.substring(14, 16));
        sb.append('-');
        sb.append(ts.substring(17, 19));
        return sb.toString();
    }

}
