#!/usr/bin/env python


#
#    Copyright (c) 2016-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
#       Implements WeaveTime class that tests Weave Time sync among Weave Nodes.
#

import os
import sys
import time

from happy.ReturnMsg import ReturnMsg
from happy.Utils import *
from happy.HappyNode import HappyNode
from happy.HappyNetwork import HappyNetwork
from plugin.WeaveTest import WeaveTest


options = {
    "client": None,
    "coordinator": None,
    "server": None,
    "mode": "auto",
    "quiet": False,
    "tap": None,
    "skip_service_end": False,
    "skip_coordinator_end": False,
    "client_faults": False,
    "server_faults": False,
    "coordinator_faults": False,
    "iterations": None,
    "test_tag": "",
    "plaid_server_env": {},
    "plaid_coordinator_env": {},
    "plaid_client_env": {}
}

gsync_succeeded_str = "Sync Succeeded"

def option():
    return options.copy()


class WeaveTime(HappyNode, HappyNetwork, WeaveTest):
    """
    weave-time [-h --help] [-q --quiet] [-c --client <NAME>] [-o --coordinator <NAME>]
               [-s --server <NAME>] [-m --mode <MODE>] [-p --tap <TAP_INTERFACE>]
               [--client_faults <fault-injection configuration>]
               [--server_faults <fault-injection configuration>]
               [--coordinator_faults <fault-injection configuration>]

    commands to test Time profile:
        $ weave-time -c node01 -o node02 -s node03 -m auto
            Time sync test among client(node01), coordinator(node02) and server(node03) with Auto mode (multicast)

        $ weave-time -c node01 -o node02 -s node03 -m local
            Time sync test among client(node01), coordinator(node02) and server(node03) with Local mode (udp)

        $ weave-time -c node01 -o node02 -s node03 -m service
            Time sync test among client(node01), coordinator(node02) and server(node03) with Service mode (tcp)

    Note:
        There are four time sync modes:
         - auto: time sync via Multicast (default)
         - local: time sync with local nodes via UDP
         - service: time sync with Service via TCP
         - service-over-tunnel: time sync with service via WRM over a weave tunnel

    return:
        0   success
        1   failure

    """
    def __init__(self, opts = options):
        HappyNode.__init__(self)
        HappyNetwork.__init__(self)
        WeaveTest.__init__(self)

        self.__dict__.update(options)
        self.__dict__.update(opts)

        self.client_process_tag = "WEAVE-TIME-CLIENT" + opts.get("test_tag")
        self.coordinator_process_tag = "WEAVE-TIME-COORDINATOR" + opts.get("test_tag")
        self.server_process_tag = "WEAVE-TIME-SERVER" + opts.get("test_tag")

        self.client_node_id = None
        self.coordinator_node_id = None
        self.server_node_id = None


    def __pre_check(self):
        # Check if Weave Time client node is given.
        if self.client == None:
            emsg = "Missing name or address of the Weave Time client node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        # Check if Weave Time coordinator node is given.
        if not self.skip_coordinator_end and self.coordinator == None:
            emsg = "Missing name or address of the Weave Time coordinator node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        # Check if Weave Time server node is given.
        if self.server == None:
            emsg = "Missing name or address of the Weave Time server node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)


        # Make sure that fabric was created
        if self.getFabricId() == None:
            emsg = "Weave Fabric has not been created yet."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        # Check if Weave Time client node exists.
        if self._nodeExists(self.client):
            self.client_node_id = self.client

        # Check if Weave Time coordinator node exists.
        if self._nodeExists(self.coordinator):
            self.coordinator_node_id = self.coordinator

        # Check if Weave Time server node exists.
        if self._nodeExists(self.server):
            self.server_node_id = self.server

        if self.client_node_id == None:
            emsg = "Unknown identity of the client node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        if not self.skip_coordinator_end and self.coordinator_node_id == None:
            emsg = "Unknown identity of the coordinator node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        if self.server_node_id == None and self.server != "service":
            emsg = "Unknown identity of the server node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        self.client_ip = self.getNodeWeaveIPAddress(self.client_node_id)
        self.client_weave_id = self.getWeaveNodeID(self.client_node_id)

        if not self.skip_coordinator_end:
            self.coordinator_ip = self.getNodeWeaveIPAddress(self.coordinator_node_id)
            self.coordinator_weave_id = self.getWeaveNodeID(self.coordinator_node_id)

        if self.server == "service":
            self.skip_service_end = True
            self.server_weave_id = self.getServiceWeaveID("Time")
            self.server_ip = self.getServiceWeaveIPAddress("Time")
        else:
            self.server_ip = self.getNodeWeaveIPAddress(self.server_node_id)
            self.server_weave_id = self.getWeaveNodeID(self.server_node_id)

        # Check if all unknowns were found

        if self.client_ip == None:
            emsg = "Could not find IP address of the client node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        if not self.skip_coordinator_end and self.coordinator_ip == None:
            emsg = "Could not find IP address of the coordinator node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        if self.server_ip == None:
            emsg = "Could not find IP address of the server node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        if self.client_weave_id == None:
            emsg = "Could not find Weave node ID of the client node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        if not self.skip_coordinator_end and self.coordinator_weave_id == None:
            emsg = "Could not find Weave node ID of the coordinator node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)

        if self.server_weave_id == None:
            emsg = "Could not find Weave node ID of the server node."
            self.logger.error("[localhost] WeaveTime: %s" % (emsg))
            sys.exit(1)


    def __process_results(self, output):
        pass_test = False

        for line in output.split("\n"):
            if gsync_succeeded_str in line:
                pass_test = True
                break

        if not self.skip_coordinator_end:
            print "weave-time test among server %s (%s), client %s (%s), coordinator %s (%s) with %s mode: " % \
                        (self.server_node_id, self.server_ip,
                         self.client_node_id, self.client_ip,
                         self.coordinator_node_id, self.coordinator_ip, self.mode)
        else:
            print "weave-time test among server %s (%s), client %s (%s) with %s mode: " % \
                        (self.server_node_id, self.server_ip,
                         self.client_node_id, self.client_ip, self.mode)

        if self.quiet == False:
            if pass_test:
                print hgreen("Time sync succeeded")
            else:
                print hred("Time sync failed")

        return (pass_test, output)


    def __start_client_side(self, block_until_sync_succeeds=False):
        cmd = self.getWeaveMockDevicePath()
        if not cmd:
            return

        cmd += " --debug-resource-usage --print-fault-counters"
        cmd += " --node-addr " + self.client_ip
        cmd += " --time-sync-client"

        if self.mode == "local":
            cmd += " --time-sync-mode-local" 

        elif self.mode == "service":                 ## TCP
            cmd += " --time-sync-mode-service"

        elif self.mode == "service-over-tunnel":     ## WRM over tunnel
            cmd += " --time-sync-mode-service-over-tunnel"
            cmd += " --ts-server-node-id " + self.server_weave_id
            cmd += " --ts-server-node-addr " + self.server_ip

        else: 
            cmd += " --time-sync-mode-auto" 

        if self.tap:
            cmd += " --interface " + self.tap

        if self.client_faults:
            cmd += " --faults " + self.client_faults

        if self.iterations:
            cmd += " --iterations " + str(self.iterations)

        if block_until_sync_succeeds:
            wait_str = gsync_succeeded_str
        else:
            # block until client weave node is ready to service weave events
            wait_str = self.ready_to_service_events_str

        self.start_weave_process(self.client_node_id, cmd, self.client_process_tag, sync_on_output=wait_str, env=self.plaid_client_env)


    def __stop_client_side(self):
        self.stop_weave_process(self.client_node_id, self.client_process_tag)

  
    def __start_coordinator_side(self):
        cmd = self.getWeaveMockDevicePath()
        if not cmd:
            return

        cmd += " --debug-resource-usage --print-fault-counters"
        cmd += " --node-addr " + self.coordinator_ip
        cmd += " --time-sync-coordinator"

        if self.tap:
            cmd += " --interface " + self.tap

        if self.coordinator_faults:
            cmd += " --faults " + self.coordinator_faults

        self.start_weave_process(self.coordinator_node_id, cmd, self.coordinator_process_tag, sync_on_output=self.ready_to_service_events_str, env=self.plaid_coordinator_env)

    def __stop_coordinator_side(self):
        self.stop_weave_process(self.coordinator_node_id, self.coordinator_process_tag)


    def __start_server_side(self):
        cmd = self.getWeaveMockDevicePath()
        if not cmd:
            return

        cmd += " --debug-resource-usage --print-fault-counters"
        cmd += " --node-addr " + self.server_ip
        cmd += " --time-sync-server"

        if self.tap:
            cmd += " --interface " + self.tap

        if self.server_faults:
            cmd += " --faults " + self.server_faults

        self.start_weave_process(self.server_node_id, cmd, self.server_process_tag, sync_on_output=self.ready_to_service_events_str, env=self.plaid_server_env)

    def __stop_server_side(self):
        self.stop_weave_process(self.server_node_id, self.server_process_tag)


    def run(self):
        self.logger.debug("[localhost] WeaveTime: Run.")

        self.__pre_check()

        # Note: in all the cases below, we don't need any synchronous and
        # deterministic wait time to allow for a time sync operation to complete
        # because the __start_client_code will block until it performs a
        # successful time sync operation (if block_until_sync_succeeds=True)

        # Note: in all cases below that includes a server simulated by a happy
        # weave node, a server restart is implicity performed as part of
        # fault-injection. This will prompt the server node to send a time
        # change notification and test if clients handle it successfully. There
        # is, hence, no need to explicitly run a server-restart test
        # (regardless of the sync mode).

        # Note: in cases where __start_client_side is invoked with
        # block_until_sync_succeeds=True, the order in which the nodes are
        # created is important. Be sure to start the server and coordinator
        # nodes before the client node is initialized, otherwise, the test will
        # fail because the client node won't get any responses from the server
        # and/or coordinator nodes (because they would not have been created).

        if self.mode == "service-over-tunnel":
            # this test presumes that the service node (mock or real), the 
            # border router and the tunnel between them have already been
            # created and initialized successfully.
            self.__start_client_side(block_until_sync_succeeds=True)

        else:
            # mode in ["auto", "local", "service"]
            self.__start_server_side()
            self.__start_coordinator_side()
            self.__start_client_side(block_until_sync_succeeds=True)

        self.__stop_client_side()

        if not self.skip_coordinator_end:
            self.__stop_coordinator_side()

        if not self.skip_service_end:
            self.__stop_server_side()

        client_output_value, client_output_data = \
            self.get_test_output(self.client_node_id, self.client_process_tag, True)
        client_strace_value, client_strace_data = \
            self.get_test_strace(self.client_node_id, self.client_process_tag, True)

        if self.skip_coordinator_end:
            coordinator_output_data = ""
            coordinator_output_value = 0
            coordinator_strace_data = ""
            coordinator_strace_value = 0
        else:
            coordinator_output_value, coordinator_output_data = \
                self.get_test_output(self.coordinator_node_id, self.coordinator_process_tag, True)
            coordinator_strace_value, coordinator_strace_data = \
                self.get_test_strace(self.coordinator_node_id, self.coordinator_process_tag, True)

        if self.skip_service_end:
            server_output_data = ""
            server_output_value = 0
            server_strace_data = ""
            server_strace_value = 0
        else:
            server_output_value, server_output_data = \
                    self.get_test_output(self.server_node_id, self.server_process_tag, True)
            server_strace_value, server_strace_data = \
                    self.get_test_strace(self.server_node_id, self.server_process_tag, True)

        avg, results = self.__process_results(client_output_data)

        data = {}
        data["client_output"] = client_output_data
        data["client_strace"] = client_strace_data
        data["coordinator_output"] = coordinator_output_data
        data["coordinator_strace"] = coordinator_strace_data
        data["server_output"] = server_output_data
        data["server_strace"] = server_strace_data

        self.logger.debug("[localhost] WeaveTime: Done.")

        return ReturnMsg(avg, data)

