/*
 * 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 org.apache.thrift.helper.*;
import uuid.Uuid;

import haxe.Int32;
import haxe.Int64;
import haxe.io.Bytes;
import haxe.ds.IntMap;
import haxe.ds.StringMap;
import haxe.ds.ObjectMap;

import thrift.test.*;  // generated code


class TestServerHandler implements ThriftTest_service {

    public var server:TServer;

    public function new() {
    }

    /**
    * Prints "testVoid()" and returns nothing.
    */
    public function testVoid():Void
    {
        trace("testVoid()");
    }

    /**
    * Prints 'testBool("%s")' where '%s' with thing as 'true' or 'false'
    * @param bool  thing - the bool data to print
    * @return bool  - returns the bool 'thing'
    *
    * @param thing
    */
    public function testBool(thing : Bool) : Bool
    {
        trace('testBool($thing)');
        return thing;
    }

    /**
    * Prints 'testString("%s")' with thing as '%s'
    * @param string thing - the string to print
    * @return string - returns the string 'thing'
    *
    * @param thing
    */
    public function testString(thing:String):String
    {
        trace("teststring(\"" + thing + "\")");
        return thing;
    }

    /**
    * Prints 'testByte("%d")' with thing as '%d'
    * @param byte thing - the byte to print
    * @return byte - returns the byte 'thing'
    *
    * @param thing
    */
    public function testByte(thing:haxe.Int32):haxe.Int32
    {
        trace("testByte(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testI32("%d")' with thing as '%d'
    * @param i32 thing - the i32 to print
    * @return i32 - returns the i32 'thing'
    *
    * @param thing
    */
    public function testI32(thing:haxe.Int32):haxe.Int32
    {
        trace("testI32(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testI64("%d")' with thing as '%d'
    * @param i64 thing - the i64 to print
    * @return i64 - returns the i64 'thing'
    *
    * @param thing
    */
    public function testI64(thing:haxe.Int64):haxe.Int64
    {
        trace("testI64(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testDouble("%f")' with thing as '%f'
    * @param double thing - the double to print
    * @return double - returns the double 'thing'
    *
    * @param thing
    */
    public function testDouble(thing:Float):Float
    {
        trace("testDouble(" + thing + ")");
        return thing;
    }

    /**
     * Prints 'testBinary("%s")' where '%s' is a hex-formatted string of thing's data
     * @param binary  thing - the binary data to print
     * @return binary  - returns the binary 'thing'
     *
     * @param thing
     */
    public function testBinary(thing : haxe.io.Bytes) : haxe.io.Bytes
    {
        var hex = "";
        for ( i in 0 ... thing.length) {
            hex += StringTools.hex( thing.get(i), 2);
        }
        trace('testBinary($hex)');
        return thing;
    }

    /**
     * Prints 'testUuid("%s")' 
     * @param Uuid  thing - the uuid to print
     * @return Uuid  - returns the uuid 'thing'
     *
     * @param thing
     */
    public function testUuid(thing : String) : String
    {
        trace('testUuid($thing)');
        return thing;
    }

    /**
    * Prints 'testStruct("{%s}")' where thing has been formatted
    *  into a string of comma separated values
    * @param Xtruct thing - the Xtruct to print
    * @return Xtruct - returns the Xtruct 'thing'
    *
    * @param thing
    */
    public function testStruct(thing:Xtruct):Xtruct
    {
        trace("testStruct({" +
                          "\"" + thing.string_thing + "\", " +
                          thing.byte_thing + ", " +
                          thing.i32_thing + ", " +
                          Int64.toStr(thing.i64_thing) + "})");
        return thing;
    }

    /**
    * Prints 'testNest("{%s}")' where thing has been formatted
    *  into a string of the nested struct
    * @param Xtruct2 thing - the Xtruct2 to print
    * @return Xtruct2 - returns the Xtruct2 'thing'
    *
    * @param thing
    */
    public function testNest(nest:Xtruct2):Xtruct2
    {
        var thing:Xtruct = nest.struct_thing;
        trace("testNest({" +
                          nest.byte_thing + ", {" +
                          "\"" + thing.string_thing + "\", " +
                          thing.byte_thing + ", " +
                          thing.i32_thing + ", " +
                          Int64.toStr(thing.i64_thing) + "}, " +
                          nest.i32_thing + "})");
        return nest;
    }

    /**
    * Prints 'testMap("{%s")' where thing has been formatted
    *  into a string of  'key => value' pairs
    *  separated by commas and new lines
    * @param map<i32,i32> thing - the map<i32,i32> to print
    * @return map<i32,i32> - returns the map<i32,i32> 'thing'
    *
    * @param thing
    */
    public function testMap(thing:IntMap<haxe.Int32>):IntMap<haxe.Int32>
    {
        trace("testMap({");
        var first:Bool = true;
        for (key in thing.keys()) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(key + " => " + thing.get(key));
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testStringMap("{%s}")' where thing has been formatted
    *  into a string of  'key => value' pairs
    *  separated by commas and new lines
    * @param map<string,string> thing - the map<string,string> to print
    * @return map<string,string> - returns the map<string,string> 'thing'
    *
    * @param thing
    */
    public function testStringMap(thing:StringMap<String>):StringMap<String>
    {
        trace("testStringMap({");
        var first:Bool = true;
        for (key in thing.keys()) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(key + " => " + thing.get(key));
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testSet("{%s}")' where thing has been formatted
    *  into a string of  values
    *  separated by commas and new lines
    * @param set<i32> thing - the set<i32> to print
    * @return set<i32> - returns the set<i32> 'thing'
    *
    * @param thing
    */
    public function testSet(thing:IntSet):IntSet
    {
        trace("testSet({");
        var first:Bool = true;
        for (elem in thing) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(elem);
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testList("{%s}")' where thing has been formatted
    *  into a string of  values
    *  separated by commas and new lines
    * @param list<i32> thing - the list<i32> to print
    * @return list<i32> - returns the list<i32> 'thing'
    *
    * @param thing
    */
    public function testList(thing:List<haxe.Int32>):List<haxe.Int32>
    {
        trace("testList({");
        var first:Bool = true;
        for (elem in thing) {
            if (first) {
                first = false;
            } else {
                trace(", ");
            };
            trace(elem);
        };
        trace("})");
        return thing;
    }

    /**
    * Prints 'testEnum("%d")' where thing has been formatted into it's numeric value
    * @param Numberz thing - the Numberz to print
    * @return Numberz - returns the Numberz 'thing'
    *
    * @param thing
    */
    public function testEnum(thing:Int):Int
    {
        trace("testEnum(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testTypedef("%d")' with thing as '%d'
    * @param UserId thing - the UserId to print
    * @return UserId - returns the UserId 'thing'
    *
    * @param thing
    */
    public function testTypedef(thing:haxe.Int64):haxe.Int64
    {
        trace("testTypedef(" + thing + ")");
        return thing;
    }

    /**
    * Prints 'testMapMap("%d")' with hello as '%d'
    * @param i32 hello - the i32 to print
    * @return map<i32,map<i32,i32>> - returns a dictionary with these values:
    *   {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, },
    *     4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, }
    *
    * @param hello
    */
    public function testMapMap(hello:haxe.Int32):IntMap<IntMap<haxe.Int32>>
    {
        trace("testMapMap(" + hello + ")");
        var mapmap = new IntMap<IntMap<Int>>();
        var pos = new IntMap<Int>();
        var neg = new IntMap<Int>();
        for (i in 1 ... 5) {
            pos.set(i, i);
            neg.set(-i, -i);
        };
        mapmap.set(4, pos);
        mapmap.set(-4, neg);
        return mapmap;
    }

    /**
    * So you think you've got this all worked, out eh?
    *
    * Creates a the returned map with these values and prints it out:
    *   { 1 => { 2 => argument,
    *            3 => argument,
    *          },
    *     2 => { 6 => <empty Insanity struct>, },
    *   }
    * @return map<UserId, map<Numberz,Insanity>> - a map with the above values
    *
    * @param argument
    */
    public function testInsanity(argument : Insanity) : Int64Map< IntMap< Insanity>>
    {
        trace("testInsanity()");

        var first_map = new IntMap< Insanity>();
        first_map.set(Numberz.TWO, argument);
        first_map.set(Numberz.THREE, argument);

        var second_map = new IntMap< Insanity>();
        var looney = new Insanity();
        second_map.set(Numberz.SIX, looney);

        var insane = new Int64Map< IntMap< Insanity>>();
        insane.set( Int64.make(0,1), first_map);
        insane.set( Int64.make(0,2), second_map);

        return insane;
    }

    /**
    * Prints 'testMulti()'
    * @param byte arg0 -
    * @param i32 arg1 -
    * @param i64 arg2 -
    * @param map<i16, string> arg3 -
    * @param Numberz arg4 -
    * @param UserId arg5 -
    * @return Xtruct - returns an Xtruct
    *    with string_thing = "Hello2, byte_thing = arg0, i32_thing = arg1
    *    and i64_thing = arg2
    *
    * @param arg0
    * @param arg1
    * @param arg2
    * @param arg3
    * @param arg4
    * @param arg5
    */
    public function testMulti(arg0:haxe.Int32, arg1:haxe.Int32, arg2:haxe.Int64,
        arg3:IntMap<String>, arg4:Int, arg5:haxe.Int64):Xtruct
    {
        trace("testMulti()");
        var hello = new Xtruct();
        hello.string_thing = "Hello2";
        hello.byte_thing = arg0;
        hello.i32_thing = arg1;
        hello.i64_thing = arg2;
        return hello;
    }

    /**
    * Print 'testException(%s)' with arg as '%s'
    * @param string arg - a string indication what type of exception to throw
    * if arg == "Xception" throw Xception with errorCode = 1001 and message = arg
    * elsen if arg == "TException" throw TException
    * else do not throw anything
    *
    * @param arg
    */
    public function testException(arg:String):Void
    {
        trace("testException(" + arg + ")");
        if (arg == "Xception") {
            var x = new Xception();
            x.errorCode = 1001;
            x.message = arg;
            throw x;
        };
        if (arg == "TException") {
            throw new TException();
        };
        return;
    }

    /**
    * Print 'testMultiException(%s, %s)' with arg0 as '%s' and arg1 as '%s'
    * @param string arg - a string indication what type of exception to throw
    * if arg0 == "Xception"
    * throw Xception with errorCode = 1001 and message = "This is an Xception"
    * else if arg0 == "Xception2"
    * throw Xception2 with errorCode = 2002 and message = "This is an Xception2"
    * else do not throw anything
    * @return Xtruct - an Xtruct with string_thing = arg1
    *
    * @param arg0
    * @param arg1
    */
    public function testMultiException(arg0:String, arg1:String):Xtruct
    {
        trace("testMultiException(" + arg0 + ", " + arg1 + ")");
        if (arg0 == "Xception") {
            var x = new Xception();
            x.errorCode = 1001;
            x.message = "This is an Xception";
            throw x;
        } else if (arg0 == "Xception2") {
            var x = new Xception2();
            x.errorCode = 2002;
            x.struct_thing = new Xtruct();
            x.struct_thing.string_thing = "This is an Xception2";
            throw x;
        };
        var result = new Xtruct();
        result.string_thing = arg1;
        return result;
    }

    /**
    * Print 'testOneway(%d): Sleeping...' with secondsToSleep as '%d'
    * sleep 'secondsToSleep'
    * Print 'testOneway(%d): done sleeping!' with secondsToSleep as '%d'
    * @param i32 secondsToSleep - the number of seconds to sleep
    *
    * @param secondsToSleep
    */
    public function testOneway(secondsToSleep:haxe.Int32):Void
    {
		#if sys
        trace("testOneway(" + secondsToSleep + "), sleeping...");
        Sys.sleep(secondsToSleep);
		#end
        trace("testOneway finished");
    }

    public function testStop():Void
    {
        if (server != null) {
            server.Stop();
        };
    }
}
