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

import org.apache.thrift.*;
import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.server.*;
import org.apache.thrift.meta_data.*;
import haxe.io.Path;

using StringTools;


enum ProtocolType {
    binary;
    json;
    compact;
}

enum EndpointTransport {
    socket;
    http;
}

enum ServerType {
    simple;
    /*
    threadpool;
    threaded;
    nonblocking;
    */
}


class Arguments
{
    public var printHelpOnly(default,null) : Bool = false;

    public var server(default,null) : Bool = false;
    public var servertype(default,null) : ServerType = simple;

    public var host(default,null) : String = "localhost";
    public var port(default,null) : Int = 9090;

    public var protocol(default,null) : ProtocolType = binary;
    public var transport(default,null) : EndpointTransport = socket;
    public var framed(default,null) : Bool = false;
    public var buffered(default,null) : Bool = false;

    public var numIterations(default,null) : Int = 1;
    public var numThreads(default,null) : Int = 1;
    public var skipSpeedTest(default,null) : Bool = false;


    public function new() {
        #if sys
        try {
              ParseArgs();
        } catch (e : String) {
            trace(GetHelp());
            throw e;
        }
        #else
        trace("WN: Platform does not support program arguments, using defaults.");
        #end
    }

    #if sys

    private static function GetHelp() : String {
        var sProg = Path.withoutDirectory( Sys.executablePath());
        return "\n"
            +sProg+"  [client|server]  [options]\n"
            +"\n"
            +"Modus: Either client or server, the default is client.\n"
            +"\n"
            +"Common options:\n"
            +"  -h [ --help ]               produce help message\n"
            +"  --port arg (=9090)          Port number to listen / connect to\n"
            /* not supported yet
            +"  --domain-socket arg         Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)\n"
            +"  --named-pipe arg            Windows Named Pipe (e.g. MyThriftPipe)\n"
            */
            +"  --protocol arg (=binary)    protocol: binary, compact, json\n"
            /* not supported yet
            +"  --ssl                       Encrypted Transport using SSL\n"
            */
            +"\n"
            +"Server only options:\n"
            +"  --transport arg (=sockets)  Transport: buffered, framed, http, anonpipe\n"
            /* not supported yet
            +"  --processor-events          processor-events\n"
            +"  --server-type arg (=simple) type of server, \"simple\", \"thread-pool\", \n"
            +"                              \"threaded\", or \"nonblocking\"\n"
            +"  -n [ --workers ] arg (=4)   Number of thread pools workers. Only valid for \n"
            +"                              thread-pool server type\n"
            */
            +"\n"
            +"Client only options:\n"
            +"  --host arg (=localhost)     Host to connect\n"
            +"  --transport arg (=sockets)  Transport: buffered, framed, http, evhttp\n"
            /* not supported yet
            +"  --anon-pipes hRead hWrite   Windows Anonymous Pipes pair (handles)\n"
            */
            +"  -n [ --testloops ] arg (=1) Number of Tests\n"
            +"  -t [ --threads ] arg (=1)   Number of Test threads\n"
            +"  --skip-speed-test           Skip the speed test\n"
            +"\n"
            +"All arguments are optional.\n"
            ;
    }


    private function ParseArgs() : Void {

        var args = Sys.args().copy();
        if( (args == null) || (args.length <= 0)) {
            server = false;
            numThreads = 1;
            return;
        }

        var arg = args.shift();
        if ( arg == "client") {
            server = false;
            numThreads = 1;
        }
        else if ( arg == "server") {
            server = true;
            numThreads = 4;
        }
        else if ( (arg == "-h") || (arg == "--help")) {
            // -h [ --help ]               produce help message
            Sys.println( GetHelp());
            printHelpOnly = true;
            return;
        }
        else {
            throw "First argument must be 'server' or 'client'";
        }


        while( args.length > 0) {
            arg = args.shift();

            if ( (arg == "-h") || (arg == "--help")) {
                // -h [ --help ]               produce help message
                Sys.println( GetHelp());
                printHelpOnly = true;
                return;
            }
            else if (arg == "--port") {
                // --port arg (=9090)          Port number to listen
                arg = args.shift();
                var tmp = Std.parseInt(arg);
                if( tmp != null) {
                    port = tmp;
                } else {
                    throw "Invalid port number "+arg;
                }
            }
            else if (arg == "--domain-socket") {
                //   --domain-socket arg         Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)
                throw "domain sockets not supported yet";
            }
            else if (arg == "--named-pipe") {
                //   --named-pipe arg            Windows Named Pipe (e.g. MyThriftPipe)
                throw "named pipes not supported yet";
            }
            else if (arg == "--protocol") {
                // --protocol arg (=binary)    protocol: binary, compact, json
                arg = args.shift();
                if( arg == "binary") {
                    protocol = binary;
                } else if( arg == "compact") {
                    protocol = compact;
                } else if( arg == "json") {
                    protocol = json;
                } else {
                    InvalidArg(arg);
                }
            }
            else if (arg == "--ssl") {
                // --ssl                       Encrypted Transport using SSL
                throw "SSL not supported yet";
            }
            else {
                //Server only options:
                if( server) {
                    ParseServerArgument( arg, args);
                } else {
                    ParseClientArgument( arg, args);
                }
            }
        }
    }


    private function ParseServerArgument( arg : String, args : Array<String>) : Void {
        if (arg == "--transport") {
            //  --transport arg (=sockets)  Transport: buffered, framed, http, anonpipe
            arg = args.shift();
            if( arg == "buffered") {
                buffered = true;
            } else if( arg == "framed") {
                framed = true;
            } else if( arg == "http") {
                transport = http;
            } else if( arg == "anonpipe") {
                throw "Anon pipes transport not supported yet";
            } else {
                InvalidArg(arg);
            }
        }
        else if (arg == "--processor-events") {
            throw "Processor events not supported yet";
        }
        else if (arg == "--server-type") {
            //  --server-type arg (=simple) type of server,
            // one of "simple", "thread-pool", "threaded", "nonblocking"
            arg = args.shift();
            if( arg == "simple") {
                servertype = simple;
            } else if( arg == "thread-pool") {
                throw arg+" server not supported yet";
            } else if( arg == "threaded") {
                throw arg+" server not supported yet";
            } else if( arg == "nonblocking") {
                throw arg+" server not supported yet";
            } else {
                InvalidArg(arg);
            }
        }
        else if ((arg == "-n") || (arg == "--workers")) {
            //  -n [ --workers ] arg (=4)   Number of thread pools workers. Only valid for
            //                              thread-pool server type
            arg = args.shift();
            var tmp = Std.parseInt(arg);
            if( tmp != null) {
                numThreads = tmp;
            } else{
                throw "Invalid number "+arg;
            }
        }
        else {
            InvalidArg(arg);
        }
    }


    private function ParseClientArgument( arg : String, args : Array<String>) : Void {
        if (arg == "--host") {
            //  --host arg (=localhost)     Host to connect
            host = args.shift();
        }
        else if (arg == "--transport") {
            //  --transport arg (=sockets)  Transport: buffered, framed, http, evhttp
            arg = args.shift();
            if( arg == "buffered") {
                buffered = true;
            } else if( arg == "framed") {
                framed = true;
            } else if( arg == "http") {
                transport = http;
            } else if( arg == "evhttp") {
                throw "evhttp transport not supported yet";
            } else {
                InvalidArg(arg);
            }
        }
        else if (arg == "--anon-pipes") {
            //  --anon-pipes hRead hWrite   Windows Anonymous Pipes pair (handles)
            throw "Anon pipes transport not supported yet";
        }
        else if ((arg == "-n") || (arg == "--testloops")) {
            //  -n [ --testloops ] arg (=1) Number of Tests
            arg = args.shift();
            var tmp = Std.parseInt(arg);
            if( tmp != null) {
                numIterations = tmp;
            } else {
                throw "Invalid number "+arg;
            }
        }
        else if ((arg == "-t") || (arg == "--threads")) {
            //  -t [ --threads ] arg (=1)   Number of Test threads
            arg = args.shift();
            var tmp = Std.parseInt(arg);
            if( tmp != null) {
                numThreads = tmp;
            } else {
                throw "Invalid number "+arg;
            }
        }
        else if (arg == "--skip-speed-test") {
            //  --skip-speed-test              Skip the speed test
            skipSpeedTest = true;
        }
        else {
            InvalidArg(arg);
        }
    }


    #end


    private function InvalidArg( arg : String) : Void {
        throw 'Invalid argument $arg';
    }
}
