// 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 common;

import java.awt.Frame;
import java.awt.ScrollPane;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.InetSocketAddress;
import java.util.Arrays;

import rdpclient.RdpClient;
import streamer.Element;
import streamer.Pipeline;
import streamer.PipelineImpl;
import streamer.SocketWrapper;
import streamer.SocketWrapperImpl;
import streamer.apr.AprSocketWrapperImpl;
import streamer.bco.BcoSocketWrapperImpl;
import streamer.ssl.SSLState;
import vncclient.VncClient;

import common.opt.IntOption;
import common.opt.Option;
import common.opt.OptionParser;
import common.opt.StringEnumerationOption;
import common.opt.StringOption;

public class Client {

    enum Protocol {
        NONE, VNC, RDP, HYPERV
    }

    // Common options
    private final Option help = new Option() {
        {
            name = "--help";
            alias = "-h";
            description = "Show this help text.";
        }
    };
    private final Option debugLink = new Option() {
        {
            name = "--debug-link";
            alias = "-DL";
            description = "Print debugging messages when packets are transferred via links.";
        }
    };
    private final Option debugElement = new Option() {
        {
            name = "--debug-element";
            alias = "-DE";
            description = "Print debugging messages when packets are received or sent by elements.";
        }
    };
    private final Option debugPipeline = new Option() {
        {
            name = "--debug-pipeline";
            alias = "-DP";
            description = "Print debugging messages in pipelines.";
        }
    };

    private final StringOption hostName = new StringOption() {
        {
            name = "--host";
            alias = "-n";
            aliases = new String[] {"--host-name"};
            required = true;
            description = "Name or IP address of host to connect to.";
        }
    };
    private final IntOption canvasWidth = new IntOption() {
        {
            name = "--width";
            alias = "-W";
            value = 1024;
            description = "Width of canvas.";
        }
    };

    private final IntOption canvasHeight = new IntOption() {
        {
            name = "--height";
            alias = "-H";
            value = 768;
            description = "Height of canvas.";
        }
    };

    // Protocol specific options

    private final IntOption vncPort = new IntOption() {
        {
            name = "--port";
            alias = "-p";
            value = 5901;
            description = "Port of VNC display server to connect to. Calculate as 5900 + display number, e.g. 5900 for display #0, 5901 for display #1, and so on.";
        }
    };

    private final IntOption rdpPort = new IntOption() {
        {
            name = "--port";
            alias = "-p";
            value = 3389;
            description = "Port of RDP server to connect to.";
        }
    };

    private final IntOption hyperVPort = new IntOption() {
        {
            name = "--port";
            alias = "-p";
            value = 2179;
            description = "Port of HyperV server to connect to.";
        }
    };

    private final StringOption password = new StringOption() {
        {
            name = "--password";
            alias = "-P";
            required = true;
            description = "Password to use.";
        }
    };

    private final StringOption rdpPassword = new StringOption() {
        {
            name = "--password";
            alias = "-P";
            required = false;
            description = "Password to use. If omitted, then login screen will be shown.";
        }
    };

    private final StringOption userName = new StringOption() {
        {
            name = "--user";
            alias = "-U";
            value = "Administrator";
            description = "User name to use.";
        }
    };

    private final StringOption domain = new StringOption() {
        {
            name = "--domain";
            alias = "-D";
            value = "Workgroup";
            description = "NTLM domain to login into.";
        }
    };

    private final StringOption hyperVInstanceId = new StringOption() {
        {
            name = "--instance";
            alias = "-i";
            required = true;
            description = "HyperV instance ID to use.";
        }
    };
    private final StringEnumerationOption sslImplementation = new StringEnumerationOption() {
        {
            name = "--ssl-implementation";
            alias = "-j";
            value = "apr";
            choices = new String[] {"jre", "apr", "bco"};
            description = "Select SSL engine to use: JRE standard implementation, Apache Portable Runtime native library, BonuncyCastle.org implementation.";
        }
    };

    private final Option[] commonOptions = new Option[] {help, debugLink, debugElement, debugPipeline, hostName, canvasWidth, canvasHeight};
    private final Option[] vncOptions = new Option[] {vncPort, password};
    private final Option[] rdpOptions = new Option[] {sslImplementation, rdpPort, domain, userName, rdpPassword};
    private final Option[] hyperVOptions = new Option[] {sslImplementation, hyperVPort, hyperVInstanceId, domain, userName, password};

    private static Frame frame;
    private static SocketWrapper socket;
    private static ScrollPane scroller;
    private static ScreenDescription screen;
    private static BufferedImageCanvas canvas;
    private InetSocketAddress address;

    private void help() {
        System.out.println("Usage: \n  java common.Client vnc|rdp|hyperv OPTIONS\n");
        System.out.println(Option.toHelp("Common options", commonOptions));
        System.out.println(Option.toHelp("VNC options", vncOptions));
        System.out.println(Option.toHelp("RDP options", rdpOptions));
        System.out.println(Option.toHelp("HyperV options", hyperVOptions));
    }

    public void runClient(String[] args) {

        try {

            Protocol protocol = parseOptions(args);
            if (protocol == Protocol.NONE)
                return;

            System.setProperty("streamer.Link.debug", "" + debugLink.used);
            System.setProperty("streamer.Element.debug", "" + debugElement.used);
            System.setProperty("streamer.Pipeline.debug", "" + debugPipeline.used);

            SSLState sslState = new SSLState();

            // Create socket wrapper
            if ("jre".equals(sslImplementation.value)) {
                socket = new SocketWrapperImpl("socket", sslState);
            } else if ("apr".equals(sslImplementation.value)) {
                socket = new AprSocketWrapperImpl("socket", sslState);
            } else if ("bco".equals(sslImplementation.value)) {
                socket = new BcoSocketWrapperImpl("socket", sslState);
            } else {
                throw new RuntimeException("Unexpected option value: \"" + sslImplementation.value + "\". " + sslImplementation.help());
            }

            screen = new ScreenDescription();
            canvas = new BufferedImageCanvas(canvasWidth.value, canvasHeight.value);
            screen.addSizeChangeListener(new SizeChangeListener() {
                @Override
                public void sizeChanged(int width, int height) {
                    if (canvas != null) {
                        canvas.setCanvasSize(width, height);
                        if (scroller != null)
                            scroller.setSize(canvas.getWidth(), canvas.getHeight());
                    }
                }
            });

            assemblePipeline(setMainElementAndAddressBasedOnProtocol(protocol, sslState));

            frame = createVncClientMainWindow(canvas, protocol.toString() + " " + hostName.value, new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent evt) {
                    shutdown();
                }
            });

            try {
                // Connect socket to remote server and run main loop(s)
                socket.connect(address);
            } finally {
                shutdown();
            }

        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
    }

    protected static void assemblePipeline(Element main) {
        Pipeline pipeline = new PipelineImpl("Client");
        pipeline.add(socket, main);
        pipeline.link("socket", main.getId(), "socket");

        pipeline.validate();
    }

    private Element setMainElementAndAddressBasedOnProtocol(Protocol protocol, SSLState sslState) {
        Element main;
        switch (protocol) {
        case VNC:
            address = new InetSocketAddress(hostName.value, vncPort.value);
            main = new VncClient("client", password.value, screen, canvas);
            break;
        case RDP:
            address = new InetSocketAddress(hostName.value, rdpPort.value);
            main = new RdpClient("client", hostName.value, domain.value, userName.value, rdpPassword.value, null, screen, canvas, sslState);
            break;
        case HYPERV:
            address = new InetSocketAddress(hostName.value, hyperVPort.value);
            main = new RdpClient("client", hostName.value, domain.value, userName.value, password.value, hyperVInstanceId.value, screen, canvas, sslState);
            break;
        default:
            address = null;
            main = null;
        }

        return main;
    }

    private Protocol parseOptions(String[] args) {
        String protocolName = (args.length > 0) ? args[0] : "";
        Protocol protocol = Protocol.NONE;

        Option[] options;
        if (protocolName.equals("vnc")) {
            protocol = Protocol.VNC;
            options = join(commonOptions, vncOptions);
        } else if (protocolName.equals("rdp")) {
            protocol = Protocol.RDP;
            options = join(commonOptions, rdpOptions);
        } else if (protocolName.equals("hyperv")) {
            protocol = Protocol.HYPERV;
            options = join(commonOptions, hyperVOptions);
        } else {
            help();
            return Protocol.NONE;
        }

        // Parse all options for given protocol
        String[] arguments = OptionParser.parseOptions(args, 1, options);

        if (arguments.length > 0) {
            System.err.println("[Client] ERROR: Arguments are not allowed here. Check command syntax. Extra arguments: \"" + Arrays.toString(arguments) + "\".");
            help();
            return Protocol.NONE;
        }

        if (help.used) {
            help();
            return Protocol.NONE;
        }
        return protocol;
    }

    protected static void shutdown() {
        if (frame != null) {
            frame.setVisible(false);
            frame.dispose();
        }
        if (socket != null)
            socket.shutdown();
    }

    protected static Frame createVncClientMainWindow(BufferedImageCanvas canvas, String title, WindowListener windowListener) {
        // Create AWT windows
        Frame frame = new Frame(title + " - RDP");

        // Use scrolling pane to support screens, which are larger than ours
        scroller = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
        scroller.add(canvas);
        scroller.setSize(canvas.getWidth(), canvas.getHeight());

        frame.add(scroller);
        frame.pack();
        frame.setVisible(true);

        frame.addWindowListener(windowListener);

        return frame;
    }

    /**
     * Join two arrays with options and return new array.
     */
    private Option[] join(Option[] a1, Option[] a2) {
        // Extend first array
        Option[] result = Arrays.copyOf(a1, a1.length + a2.length);

        // Append second array to first
        for (int i = 0, p = a1.length; i < a2.length; i++, p++)
            result[p] = a2[i];

        return result;
    }

    public static void main(String args[]) {
        // *DEBUG*/System.setProperty("javax.net.debug", "ssl");
        // * DEBUG */System.setProperty("javax.net.debug", "ssl:record:packet");

        new Client().runClient(args);
    }

}
