/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package usda.weru.util;

import de.schlichtherle.io.File;
import de.schlichtherle.io.swing.FileSystemView;
import java.awt.Image;
import java.io.IOException;
import java.net.InetAddress;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.RootLogger;
import usda.weru.resources.Resources;

/**
 *
 * @author joelevin
 */
public class About {

    private static final String VERSION_MAJOR = "version.major";
    private static final String VERSION_MINOR = "version.minor";
    private static final String VERSION_RELEASE = "version.release";
    private static final String BUILD_NUMBER = "build.number";
    private static final String BUILD_RELEASE = "build.release";
    private static final String BUILD_REVISON = "build.revision";
    private static final String BUILD_DATE = "build.date";
    private static final String RELEASE_ID = "release.id";
    private static Properties c_properties;

    private synchronized static Properties getBuildProperties() {
        if (c_properties == null) {
            c_properties = new Properties();
            try {
                c_properties.load(About.class.getResourceAsStream("/build.properties"));
            } catch (IOException ioe) {
                Logger.getLogger(About.class).warn("Unable to load build.properties.", ioe);
            }
            catch(Exception e){
                Logger.getLogger(About.class).warn("build.properties was not found.");
            }
        }
        return c_properties;
    }

    public static String getVersion() {        
        return getMajorVersion() + "." + getMinorVersion() + "." + getReleaseVersion();
    }

    public static int getMajorVersion() {
        int major = 0;
        String text = getBuildProperties().getProperty(VERSION_MAJOR, "0");
        text = text != null && text.length() > 0 ? text.trim() : "0";
        try {
            major = Integer.valueOf(text);
        } catch (NumberFormatException nfe) {
            major = -1;
            Logger.getLogger(About.class).warn("Unable to parse build.version: " + text);
        }
        return major;

    }

    public static int getMinorVersion() {
        int minor = 0;
        String text = getBuildProperties().getProperty(VERSION_MINOR, "0");
        text = text != null && text.length() > 0 ? text.trim() : "0";
        try {
            minor = Integer.valueOf(text);
        } catch (NumberFormatException nfe) {
            minor = -1;
            Logger.getLogger(About.class).warn("Unable to parse build.version: " + text);
        }
        return minor;
    }

    public static int getReleaseVersion() {
        int minor = 0;
        String text = getBuildProperties().getProperty(VERSION_RELEASE, "0");
        text = text != null && text.length() > 0 ? text.trim() : "0";
        try {
            minor = Integer.valueOf(text);
        } catch (NumberFormatException nfe) {
            minor = -1;
            Logger.getLogger(About.class).warn("Unable to parse build.version: " + text);
        }
        return minor;
    }

    public static int getBuildNumber() {
        int number = 0;
        String text = getBuildProperties().getProperty(BUILD_NUMBER, "0");
        text = text != null && text.length() > 0 ? text.trim() : "0";
        try {
            number = Integer.valueOf(text);
        } catch (NumberFormatException nfe) {
            number = -1;
            Logger.getLogger(About.class).warn("Unable to parse build.number: " + text);
        }
        return number;
    }
    
    public static String getBuildRelease(){
        String text = getBuildProperties().getProperty(BUILD_RELEASE, "development");
        if (text == null || text.trim().length() == 0){
            text = "development";
        }
        return text.trim();
    }
    
    public static int getBuildRevision() {
        int number = -1;
        String text = getBuildProperties().getProperty(BUILD_REVISON, "-1");
        text = text != null && text.length() > 0 ? text.trim() : "-1";
        try {
            number = Integer.valueOf(text);
        } catch (NumberFormatException nfe) {
            number = -1;
            Logger.getLogger(About.class).warn("Unable to parse build.revision: " + text);
        }
        return number;
    }
    
    public static Date getBuildDate(){
        String text = getBuildProperties().getProperty(BUILD_DATE, null);        
        if (text == null || text.trim().length() == 0){
            return null;
        }
        
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");        
        try{            
            return format.parse(text.trim());
        }
        catch(ParseException pe){
            Logger.getLogger(About.class).warn("Unable to parse build.date: " + text);
            return null;
        }                
    }

    public static String getJava() {
        return System.getProperty("java.version") + " from " + System.getProperty("java.vendor");
    }

    public static String getSystem() {
        return System.getProperty("os.name") + " " + System.getProperty("os.version") + " running on " + System.getProperty("os.arch") + "; " + System.getProperty("file.encoding") + "; " + Locale.getDefault().toString();
    }
    
    public static String getOS() {
        return System.getProperty("os.name");
    }

    public static String getOSVersion() {
        return System.getProperty("os.version");
    }
    
    public static String getPlatform() {
        return System.getProperty("os.arch");
    }
    public static File getConfig() {
        try{
            return ConfigData.getDefault().getMainFile();
        }
        catch(NullPointerException npe){
            return null;
        }
    }

    public static String getUserName(){
        return System.getProperty("user.name");
    }

    public static String getHostName(){
        try{
            return InetAddress.getLocalHost().getHostName();
        }
        catch(Exception e){
            return "";
        }

    }

    public static String getReleaseId(){
        String text = getBuildProperties().getProperty(RELEASE_ID, "dev");
        if (text == null || text.trim().length() == 0){
            text = "dev";
        }
        return text.trim();
    }

    public static String getHostAddress(){
        try{
            return InetAddress.getLocalHost().getHostAddress();
        }
        catch(Exception e){
            return "0.0.0.0";
        }

    }

    public static File getUserConfig() {
        try{
            return ConfigData.getDefault().getUserFile();
        }
        catch(NullPointerException npe){
            return null;
        }
    }
    
    private static File c_logConfig;

    public static File getLogConfig() {
        return c_logConfig;
    }
    
    public static void setLogConfig(File file){
        c_logConfig = file;
    }

    public static File getLog() {
        Appender appender = RootLogger.getRootLogger().getAppender("file");
        if (appender instanceof FileAppender) {
            FileAppender fa = (FileAppender) appender;
            String log = fa.getFile();
            if (log != null) {
                return new File(log);
            }
        }
        return null;
    }
    
    public static File getUserHome(){
        return new File(System.getProperty("user.home"));
    }
    
    public static File getUserDocuments(){
        return new File(FileSystemView.getFileSystemView().getDefaultDirectory());
    }
    
    private static File c_userWepsRoot;

    public static File getUserWepsRoot(){
        return c_userWepsRoot != null ? c_userWepsRoot : new File(getUserHome(), ".weps/");
    }
    
    public static void setUserWepsRoot(File file){
        c_userWepsRoot = file;
    }

    public static File getUserWeps(){
        return new File(getUserWepsRoot(), getReleaseId() + "_" + getVersion());
    }
    
    public static File getUserWorking(){
        return new File(System.getProperty("user.dir"));
    }

    public static Image getWeruIconImage(){
        return Resources.getImage("weruface.gif");
    }

    /**
     * File location for the databases.  This is typically a shared space on the machine.
     * Search Order:
     * 1. Environment variable : WEPS_DATABASES, we be the way *nix systems setup their databases
     *
     * 2 & 3 only on windows boxes
     * 2. %programdata%\weps\databases\, will be the location on vista/7/+ systems
     * 3. %allusersprofile%\Application Data\weps\databases\, will be the location on legacy systems(XP)
     * @return
     */
    public static File getWepsDatabases(){

         //1, we use the environment variable if it is avaliable
            String env = System.getenv("WEPS_DATABASES");
            if(env != null && env.trim().length() > 0){
                return new File(env);
            }

            //if windows then we attempt to figure out where the databases are
            if(Util.isWindows()){
                File result = null;
                //2, %progamdata%\weps\databases
                String programdataPath = System.getenv("programdata");
                if(programdataPath != null && programdataPath.trim().length() > 0){
                    result = new File(programdataPath, "USDA\\WEPS\\Databases");
                    if(result.isDirectory()){
                        return result;
                    }
                }

                //3. %allusersprofile%\Application Data\weps\databases\,                
                String allusersprofilePath = System.getenv("allusersprofile");
                if(allusersprofilePath != null && allusersprofilePath.trim().length() > 0){
                    result = new File(allusersprofilePath,"Application Data\\USDA\\WEPS\\Databases");
                    if(result.isDirectory()){
                        return result;
                    }
                }
                

                return new File(".").getCanOrAbsFile();


            }
            else{
                return new File("").getCanOrAbsFile();
            }

            
    }
}
