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

        Option[] options;
        try {
            protocol = Protocol.valueOf(protocolName);
        } catch (IllegalArgumentException e) {
            protocol = Protocol.NONE;
        }

        switch (protocol) {
            case VNC:
                options = join(commonOptions, vncOptions);
                break;
            case RDP:
                options = join(commonOptions, rdpOptions);
                break;
            case HYPERV:
                options = join(commonOptions, hyperVOptions);
                break;
            default:
                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);
    }

}
