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

// Distributed under the Thrift Software License
//
// See accompanying file LICENSE or visit the Thrift site at:
// http://developers.facebook.com/thrift/
using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using Thrift.Collections;
using Thrift.Test; //generated code
using Thrift.Transport;
using Thrift.Protocol;
using Thrift.Server;
using Thrift;
using System.Threading;
using System.Text;
using System.Security.Authentication;

namespace Test
{
    public class TestServer
    {
        public static int _clientID = -1;
        public delegate void TestLogDelegate(string msg, params object[] values);

        public class TradeServerEventHandler : TServerEventHandler
        {
            public int callCount = 0;
            public void preServe()
            {
                callCount++;
            }
            public Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
            {
                callCount++;
                return null;
            }
            public void deleteContext(Object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output)
            {
                callCount++;
            }
            public void processContext(Object serverContext, Thrift.Transport.TTransport transport)
            {
                callCount++;
            }
        };


        public class TestHandler : ThriftTest.Iface, Thrift.TControllingHandler
        {
            public TServer server { get; set; }
            private int handlerID;
            private StringBuilder reusableStringBuilder = new StringBuilder();
            private TestLogDelegate testLogDelegate;

            public TestHandler()
            {
                handlerID = Interlocked.Increment(ref _clientID);
                testLogDelegate += testConsoleLogger;
                testLogDelegate.Invoke("New TestHandler instance created");
            }

            public void testConsoleLogger(string msg, params object[] values)
            {
                reusableStringBuilder.Clear();
                reusableStringBuilder.AppendFormat("handler{0:D3}:",handlerID);
                reusableStringBuilder.AppendFormat(msg, values);
                reusableStringBuilder.AppendLine();
                Console.Write( reusableStringBuilder.ToString() );
            }

            public void testVoid()
            {
                testLogDelegate.Invoke("testVoid()");
            }

            public string testString(string thing)
            {
                testLogDelegate.Invoke("testString({0})", thing);
                return thing;
            }

            public bool testBool(bool thing)
            {
                testLogDelegate.Invoke("testBool({0})", thing);
                return thing;
            }

            public sbyte testByte(sbyte thing)
            {
                testLogDelegate.Invoke("testByte({0})", thing);
                return thing;
            }

            public int testI32(int thing)
            {
                testLogDelegate.Invoke("testI32({0})", thing);
                return thing;
            }

            public long testI64(long thing)
            {
                testLogDelegate.Invoke("testI64({0})", thing);
                return thing;
            }

            public double testDouble(double thing)
            {
                testLogDelegate.Invoke("testDouble({0})", thing);
                return thing;
            }

            public byte[] testBinary(byte[] thing)
            {
                string hex = BitConverter.ToString(thing).Replace("-", string.Empty);
                testLogDelegate.Invoke("testBinary({0:X})", hex);
                return thing;
            }

            public Xtruct testStruct(Xtruct thing)
            {
                testLogDelegate.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing.String_thing, thing.Byte_thing, thing.I32_thing, thing.I64_thing);
                return thing;
            }

            public Xtruct2 testNest(Xtruct2 nest)
            {
                Xtruct thing = nest.Struct_thing;
                testLogDelegate.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})",
                                 nest.Byte_thing,
                                 thing.String_thing,
                                 thing.Byte_thing,
                                 thing.I32_thing,
                                 thing.I64_thing,
                                 nest.I32_thing);
                return nest;
            }

            public Dictionary<int, int> testMap(Dictionary<int, int> thing)
            {
                reusableStringBuilder.Clear();
                reusableStringBuilder.Append("testMap({{");
                bool first = true;
                foreach (int key in thing.Keys)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        reusableStringBuilder.Append(", ");
                    }
                    reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]);
                }
                reusableStringBuilder.Append("}})");
                testLogDelegate.Invoke(reusableStringBuilder.ToString());
                return thing;
            }

            public Dictionary<string, string> testStringMap(Dictionary<string, string> thing)
            {
                reusableStringBuilder.Clear();
                reusableStringBuilder.Append("testStringMap({{");
                bool first = true;
                foreach (string key in thing.Keys)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        reusableStringBuilder.Append(", ");
                    }
                    reusableStringBuilder.AppendFormat("{0} => {1}", key, thing[key]);
                }
                reusableStringBuilder.Append("}})");
                testLogDelegate.Invoke(reusableStringBuilder.ToString());
                return thing;
            }

            public THashSet<int> testSet(THashSet<int> thing)
            {
                reusableStringBuilder.Clear();
                reusableStringBuilder.Append("testSet({{");
                bool first = true;
                foreach (int elem in thing)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        reusableStringBuilder.Append(", ");
                    }
                    reusableStringBuilder.AppendFormat("{0}", elem);
                }
                reusableStringBuilder.Append("}})");
                testLogDelegate.Invoke(reusableStringBuilder.ToString());
                return thing;
            }

            public List<int> testList(List<int> thing)
            {
                reusableStringBuilder.Clear();
                reusableStringBuilder.Append("testList({{");
                bool first = true;
                foreach (int elem in thing)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        reusableStringBuilder.Append(", ");
                    }
                    reusableStringBuilder.AppendFormat("{0}", elem);
                }
                reusableStringBuilder.Append("}})");
                testLogDelegate.Invoke(reusableStringBuilder.ToString());
                return thing;
            }

            public Numberz testEnum(Numberz thing)
            {
                testLogDelegate.Invoke("testEnum({0})", thing);
                return thing;
            }

            public long testTypedef(long thing)
            {
                testLogDelegate.Invoke("testTypedef({0})", thing);
                return thing;
            }

            public Dictionary<int, Dictionary<int, int>> testMapMap(int hello)
            {
                testLogDelegate.Invoke("testMapMap({0})", hello);
                Dictionary<int, Dictionary<int, int>> mapmap =
                  new Dictionary<int, Dictionary<int, int>>();

                Dictionary<int, int> pos = new Dictionary<int, int>();
                Dictionary<int, int> neg = new Dictionary<int, int>();
                for (int i = 1; i < 5; i++)
                {
                    pos[i] = i;
                    neg[-i] = -i;
                }

                mapmap[4] = pos;
                mapmap[-4] = neg;

                return mapmap;
            }

            // Insanity
            // returns:
            // { 1 => { 2 => argument,
            //          3 => argument,
            //        },
            //   2 => { 6 => <empty Insanity struct>, },
            // }
            public Dictionary<long, Dictionary<Numberz, Insanity>> testInsanity(Insanity argument)
            {
                testLogDelegate.Invoke("testInsanity()");

                Dictionary<Numberz, Insanity> first_map = new Dictionary<Numberz, Insanity>();
                Dictionary<Numberz, Insanity> second_map = new Dictionary<Numberz, Insanity>(); ;

                first_map[Numberz.TWO] = argument;
                first_map[Numberz.THREE] = argument;

                second_map[Numberz.SIX] = new Insanity();

                Dictionary<long, Dictionary<Numberz, Insanity>> insane =
                  new Dictionary<long, Dictionary<Numberz, Insanity>>();
                insane[(long)1] = first_map;
                insane[(long)2] = second_map;

                return insane;
            }

            public Xtruct testMulti(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5)
            {
                testLogDelegate.Invoke("testMulti()");

                Xtruct 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
             */
            public void testException(string arg)
            {
                testLogDelegate.Invoke("testException({0})", arg);
                if (arg == "Xception")
                {
                    Xception x = new Xception();
                    x.ErrorCode = 1001;
                    x.Message = arg;
                    throw x;
                }
                if (arg == "TException")
                {
                    throw new Thrift.TException();
                }
                return;
            }

            public Xtruct testMultiException(string arg0, string arg1)
            {
                testLogDelegate.Invoke("testMultiException({0}, {1})", arg0,arg1);
                if (arg0 == "Xception")
                {
                    Xception x = new Xception();
                    x.ErrorCode = 1001;
                    x.Message = "This is an Xception";
                    throw x;
                }
                else if (arg0 == "Xception2")
                {
                    Xception2 x = new Xception2();
                    x.ErrorCode = 2002;
                    x.Struct_thing = new Xtruct();
                    x.Struct_thing.String_thing = "This is an Xception2";
                    throw x;
                }

                Xtruct result = new Xtruct();
                result.String_thing = arg1;
                return result;
            }

            public void testStop()
            {
                if (server != null)
                {
                    server.Stop();
                }
            }

            public void testOneway(int arg)
            {
                testLogDelegate.Invoke("testOneway({0}), sleeping...", arg);
                System.Threading.Thread.Sleep(arg * 1000);
                testLogDelegate.Invoke("testOneway finished");
            }

        } // class TestHandler

        private enum ServerType
        {
            TSimpleServer,
            TThreadedServer,
            TThreadPoolServer,
        }

        private enum ProcessorFactoryType
        {
            TSingletonProcessorFactory,
            TPrototypeProcessorFactory,
        }

        public static bool Execute(string[] args)
        {
            try
            {
                bool useBufferedSockets = false, useFramed = false, useEncryption = false, compact = false, json = false;
                ServerType serverType = ServerType.TSimpleServer;
                ProcessorFactoryType processorFactoryType = ProcessorFactoryType.TSingletonProcessorFactory;
                int port = 9090;
                string pipe = null;
                for (int i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-pipe")  // -pipe name
                    {
                        pipe = args[++i];
                    }
                    else if (args[i].Contains("--port="))
                    {
                        port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1));
                    }
                    else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
                    {
                        useBufferedSockets = true;
                    }
                    else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
                    {
                        useFramed = true;
                    }
                    else if (args[i] == "--compact" || args[i] == "--protocol=compact")
                    {
                        compact = true;
                    }
                    else if (args[i] == "--json" || args[i] == "--protocol=json")
                    {
                        json = true;
                    }
                    else if (args[i] == "--threaded" || args[i] == "--server-type=threaded")
                    {
                        serverType = ServerType.TThreadedServer;
                    }
                    else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool")
                    {
                        serverType = ServerType.TThreadPoolServer;
                    }
                    else if (args[i] == "--prototype" || args[i] == "--processor=prototype")
                    {
                        processorFactoryType = ProcessorFactoryType.TPrototypeProcessorFactory;
                    }
                    else if (args[i] == "--ssl")
                    {
                        useEncryption = true;
                    }
                }

                // Transport
                TServerTransport trans;
                if (pipe != null)
                {
                    trans = new TNamedPipeServerTransport(pipe);
                }
                else
                {
                    if (useEncryption)
                    {
                        string certPath = "../keys/server.p12";
                        trans = new TTLSServerSocket(port, 0, useBufferedSockets, new X509Certificate2(certPath, "thrift"), 
                            null,
                            null, SslProtocols.Tls);
                    }
                    else
                    {
                        trans = new TServerSocket(port, 0, useBufferedSockets);
                    }
                }

                TProtocolFactory proto;
                if (compact)
                    proto = new TCompactProtocol.Factory();
                else if (json)
                    proto = new TJSONProtocol.Factory();
                else
                    proto = new TBinaryProtocol.Factory();

                TProcessorFactory processorFactory;
                if (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory)
                {
                    processorFactory = new TPrototypeProcessorFactory<ThriftTest.Processor, TestHandler>();
                }
                else
                {
                    // Processor
                    TestHandler testHandler = new TestHandler();
                    ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler);
                    processorFactory = new TSingletonProcessorFactory(testProcessor);
                }

                TTransportFactory transFactory;
                if (useFramed)
                    transFactory = new TFramedTransport.Factory();
                else
                    transFactory = new TTransportFactory();

                TServer serverEngine;
                switch (serverType)
                {
                    case ServerType.TThreadPoolServer:
                        serverEngine = new TThreadPoolServer(processorFactory, trans, transFactory, proto);
                        break;
                    case ServerType.TThreadedServer:
                        serverEngine = new TThreadedServer(processorFactory, trans, transFactory, proto);
                        break;
                    default:
                        serverEngine = new TSimpleServer(processorFactory, trans, transFactory, proto);
                        break;
                }

                //Server event handler
                TradeServerEventHandler serverEvents = new TradeServerEventHandler();
                serverEngine.setEventHandler(serverEvents);

                // Run it
                string where = (pipe != null ? "on pipe " + pipe : "on port " + port);
                Console.WriteLine("Starting the " + serverType.ToString() + " " + where +
                    (processorFactoryType == ProcessorFactoryType.TPrototypeProcessorFactory ? " with processor prototype factory " : "") +
                    (useBufferedSockets ? " with buffered socket" : "") +
                    (useFramed ? " with framed transport" : "") +
                    (useEncryption ? " with encryption" : "") +
                    (compact ? " with compact protocol" : "") +
                    (json ? " with json protocol" : "") +
                    "...");
                serverEngine.Serve();

            }
            catch (Exception x)
            {
                Console.Error.Write(x);
                return false;
            }
            Console.WriteLine("done.");
            return true;
        }
    }
}
