#!/usr/bin/env python


#
#    Copyright (c) 2015-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 WeaveWRMP class that tests Weave Echo 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
import plugins.plaid.Plaid as Plaid

options = {
    "client" : None,
    "server" : None,
    "quiet" : False,
    "test" : None,
    "retransmit" : None,
    "tap" : None,
    "strace" : True,
    "plaid" : "auto",
    "use_persistent_storage": True
}


def option():
    return options.copy()


class WeaveWRMP(HappyNode, HappyNetwork, WeaveTest):
    """
    weave-wrmp [-h --help] [-q --quiet] [-c --client <NAME>] [-s --server <NAME>]
           [-t --test] [-r --retransmit <TIME_MICRO>]

    return:
        0    success
        1    fail
    """
    def __init__(self, opts = {}):
        HappyNode.__init__(self)
        HappyNetwork.__init__(self)
        WeaveTest.__init__(self)

        defaultValues = dict(options)
        defaultValues.update(opts)

        self.__dict__.update(defaultValues)

        self.server_process_tag = "WEAVE-WRMP-SERVER" + (opts['test_tag'] if 'test_tag' in opts else '')
        self.client_process_tag = "WEAVE-WRMP-CLIENT" + (opts['test_tag'] if 'test_tag' in opts else '')
        self.plaid_server_process_tag = "PLAID_SERVER" + (opts['test_tag'] if 'test_tag' in opts else '')

        self.client_node_id = None
        self.server_node_id = None
        plaid_opts = Plaid.default_options()
        plaid_opts['quiet'] = self.quiet
        self.plaid_server_node_id = 'node03'
        plaid_opts['server_node_id'] = self.plaid_server_node_id
        plaid_opts['num_clients'] = 2
        plaid_opts['server_ip_address'] = self.getNodeWeaveIPAddress(self.plaid_server_node_id)
        plaid_opts['strace'] = self.strace
        self.plaid = Plaid.Plaid(plaid_opts)

        self.use_plaid = opts["plaid"]
        if opts["plaid"] == "auto":
            self.use_plaid = self.plaid.isPlaidConfigured()


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

        # Check if Weave WRMP server node is given.
        if self.server == None:
            emsg = "Missing name or address of the Weave WRMP server node."
            self.logger.error("[localhost] WeaveWRMP: %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] WeaveWRMP: %s" % (emsg))
            sys.exit(1)

        if self.test != None:
            self.test = int(float(self.test))
        else:
            self.test = 1

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

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

        # Check if client is provided in a form of IP address
        if self.isIpAddress(self.client):
            self.client_node_id = self.getNodeIdFromAddress(self.client)

        # Check if server is provided in a form of IP address
        if self.isIpAddress(self.server):
            self.server_node_id = self.getNodeIdFromAddress(self.server)

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

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

        self.client_ip = self.getNodeWeaveIPAddress(self.client_node_id)
        self.server_ip = self.getNodeWeaveIPAddress(self.server_node_id)
        self.client_weave_id = self.getWeaveNodeID(self.client_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] WeaveWRMP: %s" % (emsg))
            sys.exit(1)

        if self.server_ip == None:
            emsg = "Could not find IP address of the server node."
            self.logger.error("[localhost] WeaveWRMP: %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] WeaveWRMP: %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] WeaveWRMP: %s" % (emsg))
            sys.exit(1)

    def __process_results(self, client_output):
        # search for 'Passed' word
        pass_test = False

        for line in client_output.split("\n"):
            if "passed" in line.lower():
                pass_test = True
                break

        if self.quiet == False:
            print "weave-wrmp from node %s (%s) to node %s (%s) : " % \
                (self.client_node_id, self.client_ip,
                 self.server_node_id, self.server_ip),
            if pass_test:
                print hgreen("PASSED")
            else:
                print hred("FAILED")

        return (pass_test, client_output)

    def __start_plaid_server(self):

        self.plaid.startPlaidServerProcess()

        emsg = "plaid-server should be running."
        self.logger.debug("[%s] WeaveWdmNext: %s" % (self.plaid_server_node_id, emsg))

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


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

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

        custom_env = {}
        if self.use_plaid:
            custom_env = self.plaid.getPlaidClientLibEnv(self.server_node_id)

        self.start_simple_weave_server(cmd, self.server_ip,
             self.server_node_id, self.server_process_tag, strace = self.strace, env = custom_env, use_persistent_storage=self.use_persistent_storage)


    def __start_client_side(self):
        cmd = self.getWeaveWRMPPath()
        if not cmd:
            return

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

        # Start WRMP client with test #
        cmd += " --test %d" % (self.test)

        if self.retransmit:
            cmd += " -R %s" % (self.retransmit)

        custom_env = {}
        if self.use_plaid:
            custom_env = self.plaid.getPlaidClientLibEnv(self.client_node_id)

        self.start_simple_weave_client(cmd, self.client_ip,
            self.server_ip, self.server_weave_id,
            self.client_node_id, self.client_process_tag,  strace = self.strace, env = custom_env, use_persistent_storage = self.use_persistent_storage)


    def __wait_for_client(self):
        self.wait_for_test_to_end(self.client_node_id, self.client_process_tag)


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


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

        self.__pre_check()

        if self.use_plaid:
            self.__start_plaid_server()

        self.__start_server_side()

        emsg = "WeaveWRMP %s should be running." % (self.server_process_tag)
        self.logger.debug("[%s] WeaveWRMP: %s" % (self.server_node_id, emsg))

        self.__start_client_side()
        self.__wait_for_client()

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

        self.__stop_server_side()

        server_output_value, server_output_data = \
            self.get_test_output(self.server_node_id, self.server_process_tag, True)

        if self.strace:
            server_strace_value, server_strace_data = \
                                 self.get_test_strace(self.server_node_id, self.server_process_tag, True)

        if self.use_plaid:
            self.__stop_plaid_server()

        status, results = self.__process_results(client_output_data)

        data = {}
        data["client_output"] = client_output_data
        data["server_output"] = server_output_data
        if self.strace:
            data["client_strace"] = client_strace_data
            data["server_strace"] = server_strace_data

        self.logger.debug("[localhost] WeaveWRMP: Done.")
        return ReturnMsg(status, data)
