/*
 * 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 weinre.server;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

//-------------------------------------------------------------------
public class ServerSettings {

    final static private String BoundHostAllConstant = "-all-";

    private int         httpPort           = 8080;
    private String      boundHost          = "localhost";
//  private boolean     useProxy           = false;
    private boolean     reuseAddr          = true;
    private boolean     verbose            = false;
    private int         readTimeoutSeconds = 5;
    private int         deathTimeoutSeconds;
    private Properties  fileProperties;
    private PrintWriter messageLog;

    //---------------------------------------------------------------
    static public ServerSettings getOptions(String[] commandLine) {
        ServerSettings settings = new ServerSettings();
        return settings.parse(commandLine);
    }

    //---------------------------------------------------------------
    private ServerSettings() {
        super();

        fileProperties = fromPropertiesFile();
    }

    //---------------------------------------------------------------
    private Options getOptions() {
        Options options = new Options();

        options.addOption("?",            false, "display help");
        options.addOption("h", "help",    false, "display help");
        options.addOption("httpPort",     true,  "tcp/ip port to use for the http server");
        options.addOption("boundHost",    true,  "host address to bind to");
        options.addOption("verbose",      true,  "display verbose logging information [true|false]");
//      options.addOption("useProxy",     true,  "enable HTTP proxy [true|false]");
        options.addOption("reuseAddr",    true,  "force bind the port if already bound [true|false]");
        options.addOption("readTimeout",  true,  "seconds before timing out HTTP GETs");
        options.addOption("deathTimeout", true,  "seconds before considering connector dead");
        options.addOption("messageLog",   true,  "file to log messages to");

        return options;
    }

    //---------------------------------------------------------------
    public Map<String,Object> asProperties() {
        Map<String,Object> result = new HashMap<String,Object>();

        result.put("httpPort",     this.httpPort + "");
        result.put("boundHost",    this.boundHost);
        result.put("boundHosts",   this.getBoundHosts());
        result.put("verbose",      this.verbose + "");
//      result.setProperty("useProxy",     this.useProxy + "");
        result.put("reuseAddr",    this.reuseAddr + "");
        result.put("readTimeout",  this.readTimeoutSeconds + "");
        result.put("deathTimeout", this.deathTimeoutSeconds + "");

        return result;
    }

    //---------------------------------------------------------------
    private Properties fromPropertiesFile() {
        Properties result = Utility.readPropertiesFile("server.properties");

        // ya, Properties doesn't trim space off values
        for (String key: result.stringPropertyNames()) {
            String val = result.getProperty(key);
            result.setProperty(key, val.trim());
        }

        return result;
    }

    //---------------------------------------------------------------
    private ServerSettings parse(String[] commandLineArgs) {
        Options options = getOptions();

        CommandLineParser parser = new PosixParser();
        CommandLine       commandLine;
        try {
            commandLine = parser.parse(options, commandLineArgs);
        }
        catch (ParseException e) {
            error(e.getMessage());
            return null;
        }

        // handle help
        if (commandLine.hasOption("?") || commandLine.hasOption("h")) {
            printHelp(options);
            return null;
        }

        // get values
        httpPort            = getIntFromOption(commandLine,     "httpPort",     httpPort,             0, 0x00FFFF);
        boundHost           = getStringFromOption(commandLine,  "boundHost",    boundHost);
        verbose             = getBooleanFromOption(commandLine, "verbose",      verbose);
//      useProxy            = getBooleanFromOption(commandLine, "useProxy",     useProxy);
        reuseAddr           = getBooleanFromOption(commandLine, "reuseAddr",    reuseAddr);
        readTimeoutSeconds  = getIntFromOption(commandLine,     "readTimeout",  readTimeoutSeconds,   0, 0x00FFFFFF);
        deathTimeoutSeconds = getIntFromOption(commandLine,     "deathTimeout", readTimeoutSeconds*3, 0, 0x00FFFF);
        messageLog          = getPrintWriterFromOption(commandLine, "messageLog");

        // handle verbose logging
        if (commandLine.hasOption("verbose")) {
            verbose = true;
        }

        return this;
    }

    //---------------------------------------------------------------
    private int getIntFromOption(CommandLine commandLine, String name, int defaultValue, int min, int max) {
        int result = defaultValue;

        String stringValue = commandLine.getOptionValue(name);
        if (null == stringValue) {
            stringValue = fileProperties.getProperty(name);
        }

        if (null == stringValue) return defaultValue;

        try {
            result = Integer.parseInt(stringValue);
        }
        catch (NumberFormatException e) {
            error(name + " parameter must be numeric");
            return result;
        }

        if ((result < min) || (result > 0x00FFFF)) {
            error(name + " parameter must be between " + min + " and " + max);
        }

        return result;
    }

    //---------------------------------------------------------------
    private String getStringFromOption(CommandLine commandLine, String name, String defaultValue) {
        String stringValue = commandLine.getOptionValue(name);
        if (null == stringValue) {
            stringValue = fileProperties.getProperty(name);
        }

        if (null == stringValue) return defaultValue;

        return stringValue;
    }

    //---------------------------------------------------------------
    private boolean getBooleanFromOption(CommandLine commandLine, String name, boolean defaultValue) {
        boolean result = defaultValue;

        String stringValue = commandLine.getOptionValue(name);
        if (null == stringValue) {
            stringValue = fileProperties.getProperty(name);
        }

        if (null == stringValue) return defaultValue;

        result = Boolean.parseBoolean(stringValue);

        return result;
    }

    //---------------------------------------------------------------
    private PrintWriter getPrintWriterFromOption(CommandLine commandLine, String name) {

        String fileName = commandLine.getOptionValue(name);
        if (null == fileName) {
            fileName = fileProperties.getProperty(name);
        }

        if (null == fileName) return null;

        File file = new File(fileName);

        try {
            FileWriter fileWriter = new FileWriter(file);
            return new PrintWriter(fileWriter);
        }
        catch (IOException e) {
            error(name + " parameter file name '" + fileName + "' cannot be opened for writing.");
            return null;
        }
    }

    //---------------------------------------------------------------
    private void error(String message) {
        System.out.println("error with command-line option: " + message);
    }

    //---------------------------------------------------------------
    private void printHelp(Options options) {
        new HelpFormatter().printHelp("java -jar weinre.jar [options]", options);
    }

    //---------------------------------------------------------------
    public int getHttpPort() {
        return httpPort;
    }

    //---------------------------------------------------------------
    public String getBoundHost() {
        return boundHost;
    }

    //---------------------------------------------------------------
    public String[] getBoundHosts() {
        if (getBoundHostValue() != null) {
            return new String[] { getBoundHost() };
        }

        ArrayList<String> hosts = new ArrayList<String>();
        List<NetworkInterface> networkInterfaces;
        try {
            networkInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
        }
        catch (SocketException e) {
            return new String[]{"localhost"};
        }

        for (NetworkInterface networkInterface: networkInterfaces) {
            List<InetAddress> inetAddresses = Collections.list(networkInterface.getInetAddresses());

            for (InetAddress inetAddress: inetAddresses) {
                hosts.add(inetAddress.getHostName());
            }
        }

        return hosts.toArray(new String[]{});
    }

    //---------------------------------------------------------------
    public String getBoundHostValue() {
        if (BoundHostAllConstant.equals(boundHost)) return null;

        return boundHost;
    }

    //---------------------------------------------------------------
    public boolean getVerbose() {
        return verbose;
    }

    //---------------------------------------------------------------
    public int getReadTimeoutSeconds() {
        return readTimeoutSeconds;
    }

    //---------------------------------------------------------------
    public int getDeathTimeoutSeconds() {
        return deathTimeoutSeconds;
    }

    //---------------------------------------------------------------
    public boolean useProxy() {
        return false; // useProxy;
    }

    //---------------------------------------------------------------
    public boolean reuseAddr() {
        return reuseAddr;
    }

    //---------------------------------------------------------------
    public PrintWriter getMessageLog() {
        return messageLog;
    }

    //---------------------------------------------------------------
    public String getNiceHostName() {
        String hostName = getBoundHostValue();
        if (null == hostName) return "localhost";
        return hostName;
    }

    //---------------------------------------------------------------
    @SuppressWarnings("unused")
    private String getSuperNiceHostName() {
        String hostName = getBoundHost();

        // get the host address used
        InetAddress inetAddress;
        try {
            inetAddress = InetAddress.getByName(hostName);
        }
        catch (UnknownHostException e) {
            Main.warn("Unable to get host address of " + hostName);
            return null;
        }

        // if it's "any local address", deal with that
        if (inetAddress.isAnyLocalAddress()) {
            try {
                InetAddress oneAddress = InetAddress.getLocalHost();
                return oneAddress.getHostName();
            }
            catch (UnknownHostException e) {
                Main.warn("Unable to get any local host address");
                return null;
            }
        }

        return inetAddress.getHostName();
    }
}
