#
# Copyright 2016 the original author or authors.
#
# Licensed 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.
#
import json
import os
from unittest import TestCase
import time
from tests.itests.docutests.test_utils import run_command_to_completion_with_raw_stdout
from tests.utests.chameleon.protoc_plugins.test_utils import load_file, \
    unindent, save_file

proto_to_yang_cmd='python -m grpc.tools.protoc -I{}  ' \
                  '--plugin=protoc-gen-custom=/voltha/experiments' \
                  '/proto2yang/proto2yang.py --custom_out={} {}'

yang_validate_cmd="pyang -f tree --ietf {}"

TEMP_PATH="/tmp/proto2yang"
TEMP_INPUT_PROTO_FILE="test.proto"
TEMP_OUTPUT_YANG_FILE="ietf-test.yang"
TEMP_PROTO_PATH='{}/{}'.format(TEMP_PATH, TEMP_INPUT_PROTO_FILE)
TEMP_YANG_PATH='{}/{}'.format(TEMP_PATH, TEMP_OUTPUT_YANG_FILE)


class ProtoToYang(TestCase):

    def setup(self):
        if not os.path.exists(TEMP_PATH):
            os.makedirs(TEMP_PATH)


    def _compare_file(self, response, expected_response):
        # compare two files and strip empty lines, blanks, etc
        def _filter(x):
            x.strip()
            return x is not None

        response = filter(_filter,response.split())
        expected_response = filter(_filter,expected_response.split())
        print response
        print expected_response

        self.assertEqual(set(response), set(expected_response))

    def _gen_yang(self, proto):
        try:
            save_file(os.path.join(TEMP_PATH, TEMP_INPUT_PROTO_FILE), proto)
            cmd = proto_to_yang_cmd.format(TEMP_PATH, TEMP_PATH, TEMP_PROTO_PATH
                                           )
            print 'running command: {}'.format(cmd)
            response, err, rc = run_command_to_completion_with_raw_stdout(cmd)
            self.assertEqual(rc, 0)

            return load_file(TEMP_YANG_PATH)
        except Exception as e:
            print('Failure to generate yang file {}'.format(e))


    def test_01_empty_proto(self):
        print "Test_01_empty_proto_Start:------------------"
        t0 = time.time()

        proto = unindent("""
            syntax = "proto3";
            package test;
        """)

        expected_response = """
            module ietf-test {
                yang-version 1.1;
                namespace "urn:ietf:params:xml:ns:yang:ietf-test";
                prefix "voltha";

                organization "CORD";
                contact
                    " Any name";

                description
                    "";

                revision "2016-11-15" {
                    description "Initial revision.";
                    reference "reference";
                }
            }
            """

        try:
            yang = self._gen_yang(proto)
            self._compare_file(yang, expected_response)
        finally:
            print "Test_01_empty_proto_End:------------------ took {} " \
                  "secs\n\n".format(time.time() - t0)


    def test_02_empty_message_with_service(self):
        print "Test_02_empty_message_with_service_Start:------------------"
        t0 = time.time()

        proto = unindent("""
            syntax = "proto3";
            package test;
            message Null {}
            service TestService {
              rpc Get(Null) returns(Null);
            }
        """)

        expected_response = """
            module ietf-test {
                yang-version 1.1;
                namespace "urn:ietf:params:xml:ns:yang:ietf-test";
                prefix "voltha";

                organization "CORD";
                contact
                    " Any name";

                description
                    "";

                revision "2016-11-15" {
                    description "Initial revision.";
                    reference "reference";
                }

                grouping Null {
                    description
                        "";
                }

                rpc TestService-Get {
                    description
                        "";
                    input {
                        uses Null;
                    }
                    output {
                        uses Null;
                    }
                }
            }
            """

        try:
            yang = self._gen_yang(proto)
            self._compare_file(yang, expected_response)
        finally:
            print "Test_02_empty_message_with_service_End:------------------ took {} " \
                  "secs\n\n".format(time.time() - t0)


    def test_03_simple_message_with_service(self):
        print "Test__03_simple_message_with_service_Start:------------------"
        t0 = time.time()

        proto = unindent("""
            syntax = "proto3";
            package test;

            // Simple Message
            message Simple {
                string str = 1; // a string attribute
                int32 int = 2; // an int32 attribute
            }

            // Service to get things done
            service TestService {

              /* Get simple answer
               *
               * Returns the true answer to all of life's persistent questions.
               */
              rpc Get(Simple) returns(Simple);
            }
            """)

        expected_response = """
            module ietf-test {
                yang-version 1.1;
                namespace "urn:ietf:params:xml:ns:yang:ietf-test";
                prefix "voltha";

                organization "CORD";
                contact
                    " Any name";

                description
                    "";

                revision "2016-11-15" {
                    description "Initial revision.";
                    reference "reference";
                }


                grouping Simple {
                    description
                        "Simple Message";
                    leaf str {
                        type string;
                        description
                            "a string attribute";
                    }

                    leaf int {
                        type int32;
                        description
                            "an int32 attribute";
                    }

                }

                /*  Service to get things done" */
                rpc TestService-Get {
                    description
                        "Get simple answer

             Returns the true answer to all of life's persistent questions.";
                    input {
                        uses Simple;
                    }
                    output {
                        uses Simple;
                    }
                }
            }
            """

        try:
            yang = self._gen_yang(proto)
            self._compare_file(yang, expected_response)
        finally:
            print "Test_03_simple_message_with_service_End" \
                  ":------------------ took {} secs\n\n".format(time.time() - t0)


    def test_04_mix_types(self):
        print "Test__04_mix_types_Start:------------------"
        t0 = time.time()

        proto = unindent("""
            syntax = "proto3";

            package experiment;

            message AsyncEvent {
                int32 seq = 1;
                enum EventType {
                    BIG_BANG = 0;  // just a big bang
                    SMALL_BANG = 1;  // so small bang
                    NO_BANG = 2;
                }
                EventType type = 2;
                string details = 3;
            }

            enum SimpleEnum {
                APPLE = 0;
                BANANA = 1;
                ORANGE = 2;
            }

            message Packet {
                int32 source = 1;
                bytes content = 2;
                message InnerPacket {
                    string url = 1;
                    string title = 2;
                    repeated string snippets = 3;
                    message InnerInnerPacket {
                        string input = 1;
                        string desc = 2;
                    }
                    repeated InnerInnerPacket inner_inner_packet = 4;
                }
                repeated InnerPacket inner_packets = 3;
            }

            message Echo {
                string msg = 1;
                float delay = 2;
            }

            message testMessage{
                string test2 = 1;
                int32 test3 = 2;
            }

            service ExperimentalService {

                rpc GetEcho(Echo) returns(Echo);

                // For server to send async stream to client
                rpc ReceiveStreamedEvents(Packet)
                    returns(stream AsyncEvent);

                // For server to send async packets to client
                rpc ReceivePackets(Echo) returns(stream Packet);

                // For client to send async packets to server
                rpc SendPackets(stream Packet) returns(Echo);

            }
            """)

        expected_response = """
            module ietf-test {
                yang-version 1.1;
                namespace "urn:ietf:params:xml:ns:yang:ietf-test";
                prefix "voltha";

                organization "CORD";
                contact
                    " Any name";

                description
                    "";

                revision "2016-11-15" {
                    description "Initial revision.";
                    reference "reference";
                }

                typedef SimpleEnum {
                    type enumeration {
                        enum APPLE {
                            description "";
                        }
                        enum BANANA {
                            description "";
                        }
                        enum ORANGE {
                            description "";
                        }
                    }
                    description
                        "";
                }

                grouping AsyncEvent {
                    description
                        "";
                    leaf seq {
                        type int32;
                        description
                            "";
                    }

                    leaf type {
                        type EventType;
                        description
                            "";
                    }

                    leaf details {
                        type string;
                        description
                            "";
                    }

                    typedef EventType {
                        type enumeration {
                            enum BIG_BANG {
                                description "";
                            }
                            enum SMALL_BANG {
                                description "";
                            }
                            enum NO_BANG {
                                description "";
                            }
                        }
                        description
                            "";
                    }

                }

                grouping Packet {
                    description
                        "";
                    leaf source {
                        type int32;
                        description
                            "";
                    }

                    leaf content {
                        type binary;
                        description
                            "";
                    }

                    list inner_packets {
                        key "url";
                        uses InnerPacket;
                        description
                            "";
                    }

                    grouping InnerPacket {
                        description
                            "";
                        leaf url {
                            type string;
                            description
                                "";
                        }

                        leaf title {
                            type string;
                            description
                                "";
                        }

                        list snippets {
                            key "snippets";
                            leaf snippets {
                                type string;
                                description
                                    "";
                            }
                            description
                                "";
                        }

                        list inner_inner_packet {
                            key "input";
                            uses InnerInnerPacket;
                            description
                                "";
                        }

                        grouping InnerInnerPacket {
                            description
                                "";
                            leaf input {
                                type string;
                                description
                                    "";
                            }

                            leaf desc {
                                type string;
                                description
                                    "";
                            }

                        }

                    }

                }

                grouping Echo {
                    description
                        "";
                    leaf msg {
                        type string;
                        description
                            "";
                    }

                    leaf delay {
                        type decimal64 {
                           fraction-digits 5;
                        }
                        description
                            "";
                    }

                }

                container testMessage {
                    description
                        "";
                    leaf test2 {
                        type string;
                        description
                            "";
                    }

                    leaf test3 {
                        type int32;
                        description
                            "";
                    }

                }

                rpc ExperimentalService-GetEcho {
                    description
                        "";
                    input {
                        uses Echo;
                    }
                    output {
                        uses Echo;
                    }
                }

                rpc ExperimentalService-ReceiveStreamedEvents {
                    description
                        "For server to send async stream to client";
                    input {
                        uses Packet;
                    }
                    output {
                        uses AsyncEvent;
                    }
                }

                rpc ExperimentalService-ReceivePackets {
                    description
                        "For server to send async packets to client";
                    input {
                        uses Echo;
                    }
                    output {
                        uses Packet;
                    }
                }

                rpc ExperimentalService-SendPackets {
                    description
                        "For client to send async packets to server";
                    input {
                        uses Packet;
                    }
                    output {
                        uses Echo;
                    }
                }


            }
            """

        try:
            yang = self._gen_yang(proto)
            self._compare_file(yang, expected_response)
        finally:
            print "Test_04_mix_types_End" \
                  ":------------------ took {} secs\n\n".format(time.time() - t0)

