/* 
 * 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 filename.
     * @param fullFilename full filename
     * @return the name of the file or folder
     */
    private String extractFileName(String fullFilename) {
        int index = fullFilename.lastIndexOf('/'); // Given path 
        return fullFilename.substring(index + 1, fullFilename.length());
    }

    /**
     * get the path from 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;
    }

}
