/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/util/org/apache/slide/util/os/Platform.java,v 1.2 2004/09/22 11:49:12 pnever Exp $
 * $Revision: 1.2 $
 * $Date: 2004/09/22 11:49:12 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 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.slide.util.os;

import java.io.File;
import java.io.IOException;
import org.apache.slide.util.Files;
import org.apache.slide.util.Properties;
import org.apache.slide.util.Strings;
import org.apache.slide.util.XAssertionFailed;

public class Platform {
    public static boolean isWindows() {
        return File.separatorChar == '\\';
    }
    
    public final char fileSeparator;
    public final char pathSeparator;
    public final String lineSeparator;
    public final String pathVariable;
    public final String nativePathVariable;
    public final String scriptSuffix;
    public final String nativeSuffix;
    private Properties environment;
    private final String setPrefix;
    private final String setSuffix;
    private final String refPrefix;
    private final String refSuffix;
    
    public static final Platform WINDOWS = new Platform('\\', ';', "\r\n", "Path", "PATH", ".cmd", ".exe", "set ", "=", "%", "%");
    public static final Platform UNIX = new Platform('/', ':', "\n", "PATH", "LD_LIBRARY_PATH", ".sh", "", "", "=", "$", "");
    public static final Platform CURRENT = isWindows()? WINDOWS : UNIX;
    
    private Platform(char fileSeparator, char pathSeparator, String lineSeparator,
                     String pathVariable, String nativePathVariable, String scriptSuffix, String nativeSuffix,
                     String setPrefix, String setSuffix,
                     String refPrefix, String refSuffix) {
        this.fileSeparator = fileSeparator;
        this.pathSeparator = pathSeparator;
        this.lineSeparator = lineSeparator;
        this.pathVariable = pathVariable;
        this.nativePathVariable = nativePathVariable;
        this.scriptSuffix = scriptSuffix;
        this.nativeSuffix = nativeSuffix;
        this.setPrefix = setPrefix;
        this.setSuffix = setSuffix;
        this.refPrefix = refPrefix;
        this.refSuffix = refSuffix;
        this.environment = null;
    }
    
    public static final File JAVA_HOME = getDirectoryProperty("java.home");
    public static final File JDK_HOME = Files.up(Platform.JAVA_HOME, new String[] { "jre" } );
    public static final File USER_DIR = getDirectoryProperty("user.dir");
    public static final File USER_HOME = getDirectoryProperty("user.home");
    
    private static File getDirectoryProperty(String name) {
        String path;
        File file;
        
        path = System.getProperty(name);
        if (path == null) {
            throw new XAssertionFailed("property not found: " + name);
        }
        file = new File(path);
        if (!file.isDirectory()) {
            throw new XAssertionFailed(name + ": no such directory: " + path);
        }
        return file;
    }
    
    public Properties getEnvironment() throws IOException {
        if (environment == null) {
            environment = loadEnvironment();
        }
        return environment;
    }

    private Properties loadEnvironment() throws IOException {
        String all;
        String[] vars;
        String var;
        int i;
        int idx;
        Executable exec;
        Properties properties;
        
        if (this == WINDOWS) {
            exec = new Executable("cmd", new String[] {"/c", "set"}, null);
        } else {
            exec = new Executable("/usr/bin/env", new String[] {}, null);
        }
        all = exec.run(USER_DIR);
        properties = new Properties();
        vars = Strings.split(all, lineSeparator);
        for (i = 0; i < vars.length; i++) {
            var = vars[i];
            idx = var.indexOf('=');
            if (idx == -1) {
                if (var.length() == 0) {
                    // ignore empty line
                } else {
                    throw new RuntimeException("invalid format: '" + var + "'");
                }
            } else {
                properties.add(var.substring(0, idx), var.substring(idx + 1));
            }
        }
        return properties;
    }
    
    /**
     * @return never null
     */
    public String getPath() throws IOException {
        return getEnvironment().get(pathVariable);
    }
    
    public String variableSet(String name, String value) {
        String result =
            setPrefix + name + setSuffix + value;
        
        if (!isWindows()) {
            result += lineSeparator + "export " + name;
        }
        return result;
    }
    
    public String variableRef(String name) {
        return refPrefix + name + refSuffix;
    }
}

