#!/usr/bin/env python

#
#    Copyright (c) 2017 Nest Labs, Inc.
#    All rights reserved.
#
#    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.
#

#
#    @file
#       Tests the following scenarios:
#       1. Fault injection tests between the Border Gateway and Tunnel
#          Front End with faults limited to tunnel establishment and
#          teardown interactions. weave-ping is used to test tunnel
#          connectivity while faults are injected.
#

import itertools
import os
import unittest
import set_test_path
import time
import json
import getopt
import sys

from happy.Utils import *
import happy.HappyNodeList
import plugins.weave.WeaveStateLoad as WeaveStateLoad
import plugins.weave.WeaveStateUnload as WeaveStateUnload
import plugin.WeavePing as WeavePing
import plugin.WeaveTunnelStart as WeaveTunnelStart
import plugin.WeaveTunnelStop as WeaveTunnelStop
import plugin.WeaveUtilities as WeaveUtilities
from plugin.WeaveTest import WeaveTest
import plugins.plaid.Plaid as Plaid


gFaultopts = WeaveUtilities.FaultInjectionOptions(nodes=["gateway", "service"])
gOptions = { 'case': True, "num_pings": "3", "restart": True }

class test_weave_tunnel_faults(unittest.TestCase):
    def setUp(self):
        self.tap = None

        if "WEAVE_SYSTEM_CONFIG_USE_LWIP" in os.environ.keys() and os.environ["WEAVE_SYSTEM_CONFIG_USE_LWIP"] == "1":
            self.topology_file = os.path.dirname(os.path.realpath(__file__)) + \
                "/../topologies/thread_wifi_on_tap_ap_service.json"
            self.tap = "wpan0"
        else:
            self.topology_file = os.path.dirname(os.path.realpath(__file__)) + \
                "/../topologies/thread_wifi_ap_service.json"

        self.show_strace = False

        # setting Mesh for thread test
        options = WeaveStateLoad.option()
        options["json_file"] = self.topology_file

        setup_network = WeaveStateLoad.WeaveStateLoad(options)
        ret = setup_network.run()

        # Wait for a second to ensure that Weave ULA addresses passed dad
        # and are no longer tentative
        time.sleep(2)

        # set up Plaid for faster execution
        plaid_opts = Plaid.default_options()
        plaid_opts['num_clients'] = 3
        plaid_opts['strace'] = self.show_strace
        self.plaid = Plaid.Plaid(plaid_opts)
        self.use_plaid = self.plaid.isPlaidConfigured()


    def tearDown(self):
        # cleaning up
        options = WeaveStateUnload.option()
        options["json_file"] = self.topology_file

        teardown_network = WeaveStateUnload.WeaveStateUnload(options)
        teardown_network.run()


    def test_weave_tunnel(self):
        # TODO: Once LwIP bugs are fix, enable this test on LwIP
        if "WEAVE_SYSTEM_CONFIG_USE_LWIP" in os.environ.keys() and os.environ["WEAVE_SYSTEM_CONFIG_USE_LWIP"] == "1":
            return

        # topology has nodes: ThreadNode, BorderRouter, onhub and cloud
        # we run tunnel between BorderRouter and cloud

        use_case = gOptions["case"]

        if self.use_plaid:
            self.__start_plaid_server()

        test_tag = "_HAPPY_SEQUENCE"

        # Start tunnel
        value_start, start_tunnel_data = self.__start_tunnel_between("BorderRouter", "cloud", use_case=use_case, test_tag=test_tag, use_plaid=self.use_plaid)

        # Run ping test
        for i in range(10):
            print "  running weave-ping between 'ThreadNode' and 'cloud' (iteration:%s/10)" %(str(i+1))
            value_ping, data_ping = self.__run_ping_test_between("ThreadNode", "cloud", use_case=False, test_tag = test_tag, use_plaid=self.use_plaid)
            if not value_ping: # 0 == SUCCESS:
                # we're done, no need for more iterations.
                break

        # Stop tunnel
        value_stop, stop_tunnel_data = self.__stop_tunnel_between("BorderRouter", "cloud", test_tag=test_tag)

        if self.use_plaid:
            self.__stop_plaid_server()

        output_logs = {}

        output_logs['gateway'] = stop_tunnel_data['gateway_output']
        output_logs['service'] = stop_tunnel_data['service_output']

        num_tests = 0
        num_failed_tests = 0
        failed_tests = []

        for node in gFaultopts.nodes:
            restart = gOptions["restart"]

            if node == "service":
                # TODO: due to a bug in mock-tunnel-service, tunnel data messages are not processed
                # after restart. Hence, all restart cases fail. Re-enable after fixing
                # mock-tunnel-service.
                restart = False

            fault_configs = gFaultopts.generate_fault_config_list(node, output_logs[node], restart)

            for fault_config in fault_configs:
                auth = "CASE" if use_case else "None"
                test_tag = "_" + auth + "_" + str(num_tests) + "_" + node + "_" + fault_config
                print "tag: " + test_tag

                if self.use_plaid:
                    self.__start_plaid_server()

                # Start tunnel
                print "  starting tunnel between 'BorderRouter' and 'cloud'"
                value_start, data_start_tunnel = self.__start_tunnel_between("BorderRouter", "cloud", use_case=use_case, num_iterations = 3, faults = {node: fault_config}, test_tag = test_tag, use_plaid=self.use_plaid)

                for i in range(15):
                    # Note that when running on plaid this loop only executes ~3 iterations in what is a minute of virtual time
                    # Without plaid, the number of iterations required is much more
                    print "  running weave-ping between 'ThreadNode' and 'cloud' (iteration:%s/15)" %(str(i+1))
                    value_ping, data_ping = self.__run_ping_test_between("ThreadNode", "cloud", use_case=False, test_tag = test_tag, use_plaid=self.use_plaid)
                    if not value_ping: # 0 == SUCCESS:
                        # we're done, no need for more iterations.
                        break

                # if tunnel goes down after ping succeeds, give it up to 15s to recover. 
                wt = WeaveTest()
                for i in range(15):
                    gw_value, gw_output = wt.get_test_output("BorderRouter", "WEAVE-GATEWAY-TUNNEL" + test_tag, quiet=True)
                    if self.__is_tunnel_up(gw_output):
                        break
                    print "  *** waiting for tunnel to recover *** (%s/15 seconds)" %(str(i+1))
                    time.sleep(1)

                # Stop tunnel
                print "  stopping tunnel between 'BorderRouter' and 'cloud'"
                value_stop, data_stop_tunnel = self.__stop_tunnel_between("BorderRouter", "cloud", test_tag = test_tag)

                if self.use_plaid:
                    self.__stop_plaid_server()

                results = self.__process_tunnel_results("BorderRouter", value_stop, data_stop_tunnel, value_ping, data_ping, test_tag=test_tag)

                success = reduce(lambda x, y: x and y, results.values())
                if not success:
                    print hred("  Failed + [" + test_tag + "]")
                    num_failed_tests += 1
                    failed_tests.append(test_tag)
                else:
                    print hgreen("  Passed [" + test_tag + "]")
                num_tests += 1

        print "  executed %d cases" % num_tests
        print "  failed %d cases:" % num_failed_tests
        if num_failed_tests > 0:
            for failed in failed_tests:
                print "    " + failed
        self.assertEqual(num_failed_tests, 0, "The above tests failed")


    def __start_tunnel_between(self, gateway, service, use_case=False, num_iterations=1, faults={}, test_tag="", block_until_tunnel_up=False, use_plaid=False):
        options = WeaveTunnelStart.option()
        options["border_gateway"] = gateway
        options["service"] = service
        options["case"] = use_case
        options["case_cert_path"] = "default"
        options["tap"] = self.tap
        options["gateway_faults"] = faults.get("gateway")
        options["service_faults"] = faults.get("service")
        options["iterations"] = num_iterations
        options["test_tag"] = test_tag

        if use_plaid:
            options["plaid_gateway_env"] = self.plaid.getPlaidClientLibEnv(gateway)
            options["plaid_service_env"] = self.plaid.getPlaidClientLibEnv(service)

        if block_until_tunnel_up:
            # wait for tunnel to be established before saying you're done
            options["sync_on_gateway_output"] = "ToState:PrimaryTunnelEstablished"

        weave_tunnel = WeaveTunnelStart.WeaveTunnelStart(options)
        ret = weave_tunnel.run()

        value = ret.Value()
        data = ret.Data()

        return value, data


    def __run_ping_test_between(self, nodeA, nodeB, use_case=False, test_tag="", use_plaid=False):
        options = WeavePing.option()
        options["clients"] = [nodeA]
        options["server"] = nodeB
        options["udp"] = True
        options["endpoint"] = "Tunnel"
        options["count"] = gOptions["num_pings"]
        options["tap"] = self.tap
        options["case"] = use_case
        options["case_cert_path"] = "default"
        options["test_tag"] = test_tag

        if use_plaid:
            options["plaid_client_env"] = self.plaid.getPlaidClientLibEnv(nodeA)
            options["plaid_server_env"] = self.plaid.getPlaidClientLibEnv(nodeB)

        weave_ping = WeavePing.WeavePing(options)
        ret = weave_ping.run()

        value = ret.Value()
        data = ret.Data()

        return value, data


    def __process_ping_result(self, nodeA, nodeB, value, data):
        num_pings = int(gOptions["num_pings"])

        print "ping from " + nodeA + " to " + nodeB + " ",

        data = data[0]

        if value > num_pings + 1:
            print hred("Failed")
        else:
            print hgreen("Passed")

        try:
            self.assertTrue(value < num_pings + 1, "%s < %s %%" % (str(value), num_pings))
        except AssertionError, e:
            print str(e)
            print "Captured experiment result:"

            print "Client Output: "
            for line in data["client_output"].split("\n"):
               print "\t" + line

            print "Server Output: "
            for line in data["server_output"].split("\n"):
                print "\t" + line

            if self.show_strace == True:
                print "Server Strace: "
                for line in data["server_strace"].split("\n"):
                    print "\t" + line

                print "Client Strace: "
                for line in data["client_strace"].split("\n"):
                    print "\t" + line

        if value > num_pings + 1:
            raise ValueError("Weave Ping over Weave Tunnel Failed")


    def __process_tunnel_results(self, gw, gw_value, gw_data, ping_value, ping_data, test_tag):

        gw_output = gw_data.get("gateway_output")
        service_output = gw_data.get("service_output")

        tunnel_up = self.__is_tunnel_up(gw_output)
        gw_parser_error, gw_leak_detected = WeaveUtilities.scan_for_leaks_and_parser_errors(gw_output)
        service_parser_error, service_leak_detected = WeaveUtilities.scan_for_leaks_and_parser_errors(service_output)

        # at the end of the test, 'tunnel_up' should be True
        if not tunnel_up:
            print hred("  Tunnel start: Failed   [" + test_tag + "]")

        if ping_value != 0:  # loss_percentage == 0
            print hred("  Ping test: Failed [" + test_tag + "]")

        if gw_parser_error is True:
            print hred("  gateway parser error  [" + test_tag + "]")

        if gw_leak_detected is True:
            print hred("  gateway leak detected [" + test_tag + "]+")

        if service_parser_error is True:
            print hred("service parser error")
        if service_leak_detected is True:
            print hred("service resource leak detected")

        result = {}
        result["tunnel_up"] = tunnel_up
        result["ping_successful"] = ping_value == 0   #loss_percentage == 0
        result["no_gw_parser_error"] = not gw_parser_error
        result["no_gw_leak_detected"] = not gw_leak_detected
        result["no_service_parser_error"] = not service_parser_error
        result["no_service_leak_detected"] = not service_leak_detected

        return result


    def __is_tunnel_up(self, gw_output):
        tunnel_up = False
        post_fault_section = False

        if not gw_output:
            return False

        gw_output = gw_output.split('\n')

        for line in gw_output:
            if "SIGUSR1 received: proceed to exit gracefully" in line:
                break

            if "***** Injecting fault" in line:
                post_fault_section = True

            if "ToState:PrimaryTunnelEstablished" in line:
                tunnel_up = True

            if "FromState:PrimaryTunnelEstablished" in line and "ToState:PrimaryTunnelEstablished" not in line:
                tunnel_up = False

            if "WEAVE:WT: Connection ABORTED" in line:
                tunnel_up = False

            if "WEAVE:WT: Tunnel connection not up" in line:
                tunnel_up = False

        return tunnel_up


    def __stop_tunnel_between(self, gateway, service, num_iterations=1, faults={}, test_tag=""):
        options = WeaveTunnelStop.option()
        options["border_gateway"] = gateway
        options["service"] = service
        options["gateway_faults"] = faults.get("gateway")
        options["service_faults"] = faults.get("service")
        options["iterations"] = num_iterations
        options["test_tag"] = test_tag
        options["sync_on_gateway_output"] = "ToState:PrimaryTunnelEstablished"

        weave_tunnel = WeaveTunnelStop.WeaveTunnelStop(options)
        ret = weave_tunnel.run()

        value = ret.Value()
        data = ret.Data()

        return value, data

    def __start_plaid_server(self):
        self.plaid.startPlaidServerProcess()

        emsg = "plaid-server should be running."
        print "test_weave_tunnel_faults: %s" % (emsg)

    def __stop_plaid_server(self):
        self.plaid.stopPlaidServerProcess()

        emsg = "plaid-server should not be running any longer."
        print "test_weave_tunnel_faults: %s" % (emsg)

if __name__ == "__main__":
    help_str = """usage:
    --help  Print this usage info and exit
    --num_pings N  Number of echo packets sent during ping test (default: 3)
    --disable-case  Turn off CASE (CASE is enabled by default)\n"""

    help_str += gFaultopts.help_string
    longopts = ["help", "num_pings=","disable-case", "no-restart"]
    longopts.extend(gFaultopts.getopt_config)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "h", longopts)

    except getopt.GetoptError as err:
        print help_str
        print hred(str(err))
        sys.exit(hred("%s: Failed to parse arguments." % (__file__)))

    opts = gFaultopts.process_opts(opts)

    for o, a in opts:
        if o in ("-h", "--help"):
            print help_str
            sys.exit(0)

        elif o in ("--disable-case"):
            gOptions["case"] = False

        elif o in ("--num_pings"):
            gOptions["num_pings"] = a

        elif o in ("--no-restart"):
            gOptions["restart"] = False

    sys.argv = [sys.argv[0]]
    WeaveUtilities.run_unittest()
