/* 
 * 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.felix.sandbox.obr.plugin;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;

/**
 * this class provide some functions to simplify file manipulation.
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class PathFile {

    /**
     * full filename.
     */
    private String m_fullFilename;

    /**
     * store only the filename of the file.
     */
    private String m_fileName;

    /**
     * store only the path of this file.
     */
    private String m_pathFile;

    /**
     * store the base Directory in case of relative path.
     */
    private String m_baseDir;

    /**
     * store the protocol used (ie:file, http...).
     */
    private String m_protocol;

    /**
     * if the path is relative or absolute.
     */
    private boolean m_relative;

    /**
     * if this file is a folder.
     */
    private boolean m_folder;

    /**
     * if the file exist or not.
     */
    private boolean m_exist;

    /**
     * if this file is a file (not a folder).
     */
    private boolean m_file;

    /**
     * if this filename is valid or incomplete.
     */
    private boolean m_valid;

    /**
     * build all the attribute information.
     * @param filename path to the file
     */
    public PathFile(String filename) {

        this.m_fullFilename = filename;
        if (filename == null) {
            this.m_valid = false;
            return;
        }
        this.m_valid = true;
        m_protocol = extractProtocol(filename);
        m_pathFile = extractPathFile(filename);
        if (m_pathFile.startsWith("//")) {
            // avoid problems on Unix like system
            m_pathFile = m_pathFile.substring(1);
        }
        m_fileName = extractFileName(filename);
        m_relative = extractRelative();
        if (!m_relative && (getProtocol().compareTo("file") == 0 || getProtocol().compareTo("") == 0)) {
            File f = new File(getOnlyAbsoluteFilename());
            m_file = f.isFile();
            m_folder = f.isDirectory();
            m_exist = f.exists();
            if (m_folder) {
                m_pathFile = m_pathFile + m_fileName + File.separator;
                m_fileName = "";
            }
        }
        if (m_exist) {
            m_protocol = "file";
        } else {
            if (m_fileName.compareTo("") == 0) {
                m_folder = true;
                m_file = false;
            } else {
                m_folder = false;
                m_file = true;
            }

        }

        // add the '/' before the complete path if it is absolute path
        if (!this.isRelative() && !m_pathFile.startsWith("/")) { m_pathFile = "/".concat(m_pathFile); }

    }

    /**
     * get if the filename is relative or absolute.
     * @return true if the path is relative, else false
     */
    private boolean extractRelative() {
        if (m_pathFile.startsWith("." + File.separator, 1) || m_pathFile.startsWith(".." + File.separator, 1)) {
            m_pathFile = m_pathFile.substring(1);
            m_valid = false;
            return true;
        }

        return false;
    }

    /**
     * get only the name from the filname.
     * @param fullFilename full filename
     * @return the name of the file or folder
     */
    private String extractFileName(String fullFilename) {
        int index = fullFilename.lastIndexOf(File.separator);
        return fullFilename.substring(index + 1, fullFilename.length());
    }

    /**
     * get the path form the filename.
     * @param fullFilename full filename
     * @return the path of the file
     */
    private String extractPathFile(String fullFilename) {
        String substring;
        if (extractFileName(fullFilename).compareTo("") == 0) {
            // it is a folder
            substring = fullFilename;
        } else {
            substring = fullFilename.substring(0, fullFilename.indexOf(extractFileName(fullFilename)));
        }

        if (getProtocol().compareTo("") != 0) {
            substring = substring.substring(5);
        }

        return substring;
    }

    /**
     * determine which protocol is used.
     * @param filename the full fileneme
     * @return "file" or "http" or ""
     */
    private String extractProtocol(String filename) {
        if (filename.startsWith("file:")) { return "file"; }
        if (filename.startsWith("http:")) { return "http"; }
        return "";
    }

    /**
     * set the base directory.
     * @param baseDir new value for the base directory
     */
    public void setBaseDir(String baseDir) {
        this.m_baseDir = baseDir;
        if (isRelative() && this.m_fullFilename != null) {
            this.m_valid = true;
            if (getProtocol().compareTo("file") == 0 || getProtocol().compareTo("") == 0) {
                File f = new File(getOnlyAbsoluteFilename());
                m_file = f.isFile();
                m_folder = f.isDirectory();
                m_exist = f.exists();
            }
            if (m_exist) {
                m_protocol = "file";
            }
        }

    }

    /**
     * get the base directory.
     * @return base directory
     */
    public String getBaseDir() {
        return this.m_baseDir;
    }

    public boolean isValid() {
        return m_valid;
    }

    public boolean isRelative() {
        return m_relative;
    }

    public boolean isExists() {
        return m_exist;
    }

    public boolean isFile() {
        return m_file;
    }

    public boolean isFolder() {
        return m_folder;
    }

    /**
     * get a File which points on the same file.
     * @return a File object
     */
    public File getFile() {
        if (!this.isValid()) { return null; }
        String path = PathFile.uniformSeparator(this.getOnlyAbsoluteFilename());
        if (File.separatorChar == '\\') { path = path.replace('\\', '/'); }
        File f = new File(path);
        return f;
    }

    /**
     * get an URI which points on the same file.
     * @return an URI object
     */
    public URI getUri() {
        if (!this.isValid()) { return null; }
        String path = PathFile.uniformSeparator(getAbsoluteFilename());
        if (File.separatorChar == '\\') { 
        	path = path.replace('\\', '/');
        	path = path.replaceAll(" ", "%20");
        }

        URI uri = null;
        try {
            uri = new URI(path);
        } catch (URISyntaxException e) {        	
            System.err.println("Malformed URI: " + path);
            System.err.println(e.getMessage());
            return null;
        }
        return uri;
    }

    /**
     * get protocol + relative path of this file.
     * @return the relative path or null if it is not valid
     */
    public String getRelativePath() {
        if (!this.isValid()) { return null; }

        return getProtocol() + ":/" + getOnlyRelativePath();
    }

    /**
     * get only (without protocol) relative path of this file.
     * @return the relative path or null if it is not valid
     */
    public String getOnlyRelativePath() {
        if (!this.isValid()) { return null; }
        if (this.isRelative()) {
            return m_pathFile;

        } else {
            if (m_baseDir != null) {
                // System.err.println(m_pathFile);
                // System.err.println(m_baseDir);
                if (m_pathFile.startsWith(m_baseDir)) {
                    /*
                     * String ch1 = m_pathFile; String ch2 = m_baseDir; System.err.println(ch1); System.err.println(ch2); System.err.println("."+File.separator+ch1.substring(ch2.length()));
                     */
                    return "." + File.separator + m_pathFile.substring(m_baseDir.length());
                }
            }
            return null;
        }
    }

    /**
     * calcul absolute path from relative path.
     * @param baseDir base directory
     * @param path path to convert
     * @return the absolute path or null
     */
    private String calculAbsolutePath(String baseDir, String path) {
        if (path.startsWith(".." + File.separatorChar)) {
            String base = baseDir;
            int lastIndex;
            lastIndex = base.lastIndexOf(File.separator);
            if (lastIndex == base.length()) {
                base = base.substring(0, base.length() - 1);
                lastIndex = base.lastIndexOf(File.separator);
            }
            if (lastIndex < base.length()) {
                return calculAbsolutePath(base.substring(0, lastIndex + 1), path.substring(3));
            } else {
                return null;
            }
        } else if (path.startsWith("." + File.separatorChar)) {
            String res;
            if (File.separatorChar == '\\') {
                res = path.replaceFirst(".", baseDir.replace('\\', '/'));
            } else {
                res = path.replaceFirst(".", baseDir);
            }

            return PathFile.uniformSeparator(res);
        } else {
            return PathFile.uniformSeparator(baseDir + path);
        }
    }

    /**
     * get only (without protocol) absolute path (without filename).
     * @return absolute path
     */
    public String getOnlyAbsolutePath() {
        if (!this.isValid()) { return null; }
        if (isRelative()) {
            return calculAbsolutePath(m_baseDir, m_pathFile);
        } else {
            return m_pathFile;
        }
    }

    /**
     * get protocol + absolute path (without filename).
     * @return absolute path
     */
    public String getAbsolutePath() {

        if (isRelative()) {
            return getProtocol() + ":/" + calculAbsolutePath(m_baseDir, m_pathFile);
        } else {
            if (getProtocol().compareTo("") == 0 || m_pathFile == null) {
                return m_pathFile;
            } else {
                return getProtocol() + ":" + m_pathFile;
            }
        }
    }

    /**
     * get only (without protocol) absolute path + filename.
     * @return absolute filename
     */
    public String getOnlyAbsoluteFilename() {
        if (getOnlyAbsolutePath() != null && getFilename() != null) {
            return getOnlyAbsolutePath() + getFilename();
        } else {
            return null;
        }
    }

    /**
     * get protocol + absolute path + filename.
     * @return absolute filenama
     */
    public String getAbsoluteFilename() {
        if (getAbsolutePath() != null && getFilename() != null) {
            return getAbsolutePath() + getFilename();
        } else {
            return null;
        }
    }

    /**
     * get only (without protocol) relative path + filename.
     * @return relative filename
     */
    public String getOnlyRelativeFilename() {
        if (!this.isValid()) { return ""; }

        return getOnlyRelativePath() + getFilename();

    }

    /**
     * get protocol + relative path + filename.
     * @return relative filename
     */
    public String getRelativeFilename() {
        if (!this.isValid()) { return ""; }

        if (this.isRelative()) {
            return getRelativePath() + getFilename();
        } else {
            return getAbsoluteFilename();
        }
    }

    public String getFilename() {
        return m_fileName;
    }

    public String getProtocol() {
        return m_protocol;
    }

    /**
     * create all the directories not also present in the current path.
     * @return true if all directories was created, else false
     */
    public boolean createPath() {
        File path = new File(this.getOnlyAbsolutePath());
        if (path.exists()) { return true; }
        return path.mkdirs();
    }

    /**
     * create all the directories not also present in the current path and the file.
     * @return true it was created, else false
     */
    public boolean createFile() {
        File path = new File(this.getOnlyAbsolutePath());
        if (!path.exists()) {
            if (!this.createPath()) { return false; }
        }
        path = new File(this.getOnlyAbsoluteFilename());
        try {
            return path.createNewFile();
        } catch (IOException e) {
            return false;
        }

    }

    /**
     * delete the current file.
     * @return true if it was deleted, else false
     */
    public boolean delete() {
        File path = new File(this.getAbsoluteFilename());
        if (path.exists()) {
            return path.delete();
        } else {
            return true;
        }

    }

    private static final String REGEXP_BACKSLASH = "\\\\";

    /**
     * replace all '\' by '\\' in the given string.
     * @param path string where replace the search pattern
     * @return string replaced
     */
    public static String doubleSeparator(String path) {
        // double the '\' in the path
        if (path != null && File.separatorChar == '\\') {
            return path.replaceAll(REGEXP_BACKSLASH, REGEXP_BACKSLASH + REGEXP_BACKSLASH);
        } else {
            return null;
        }
    }

    /**
     * file separator('\' or '/') by the one of the current system.
     * @param path string where replace the search pattern
     * @return string replaced
     */
    public static String uniformSeparator(String path) {
        if (File.separatorChar == '\\') {
            if (path.startsWith("/")) {
                return path.substring(1).replace('/', File.separatorChar);
            } else {
                return path.replace('/', File.separatorChar);
            }
        } else {
            return path.replace('\\', File.separatorChar);
        }
    }

    /**
     * copy file from src to dest.
     * @param src source file
     * @param dest destination file
     * @return true if the file was correctly copied, else false
     */
    public static boolean copyFile(PathFile src, PathFile dest) {
        FileChannel in = null;
        FileChannel out = null;

        if (!src.isExists()) {
            System.err.println("src file must exist: " + src.getAbsoluteFilename());
            return false;
        }
        if (!dest.isExists()) {
            dest.createFile();
        }
        try {
            in = new FileInputStream(src.getOnlyAbsoluteFilename()).getChannel();
            out = new FileOutputStream(dest.getOnlyAbsoluteFilename()).getChannel();

            in.transferTo(0, in.size(), out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    return false;
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    return false;
                }
            }
        }
        return true;
    }

}
