#!/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 WeaveBDX class that tests Weave BDX 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 plugin.WeaveUtilities as WeaveUtilities
import plugins.plaid.Plaid as Plaid


options = {}
options["quiet"] = False
options["server"] = None
options["client"] = None
options["tmp"] = None
options["receive"] = None
options["download"] = None
options["upload"] = None
options["offset"] = None
options["length"] = None
options["tap"] = None
options["server_version"] = 1
options["client_version"] = 1
options["client_faults"] = None
options["server_faults"] = None
options["strace"] = True
options["test_tag"] = ""
options["iterations"] = 1
options["plaid"] = False


def option():
    return options.copy()


class WeaveBDX(HappyNode, HappyNetwork, WeaveTest):
    """
    weave-bdx [-h --help] [-q --quiet] [-s --server <NAME>] [-c --client <NAME>]
           [-t --tmp <SERVER_TMP_PATH>] [-r --receive <DESTINATION_PATH>]
           [-u --upload <SOURCE_PATH>] [-d --download <SOURCE_PATH>]
           [-o --offset <SIZE>] [-l --length <SIZE>] [-p --tap <TAP_INTERFACE>]
           [-S --server-version <bdx_version>] [-C --client-version <bdx_version>]


    commands to test bdx-v0:
        $ weave-bdx -s node01 -c node02 -S 0 -C 0 --upload /client_files/test_file.txt --tmp /server/tmp --receive /server_files
            Sends /client_files/test_file.txt from node02 to folder /server_files at node01.

        $ weave-bdx -s node01 -c node02 -S 0 -C 0 --download /server_files/test_file.txt --tmp /server/tmp --receive /client_files
            Receives /server_files/test_file.txt from node01 at /client_files of node02.

    commands to test bdx-v1:
        $ weave-bdx -s node01 -c node02 -S 1 -C 1 --upload /client_files/test_file.txt --tmp /server/tmp --receive /server_files
            Sends /client_files/test_file.txt from node02 to folder /server_files at node01.

        $ weave-bdx -s node01 -c node02 -S 1 -C 1 --download /server_files/test_file.txt --tmp /server/tmp --receive /client_files
            Receives /server_files/test_file.txt from node01 at /client_files of node02.

    commands to test bdx-v0 and bdx-v1 interop:
        $ weave-bdx -s node01 -c node02 -S 0 -C 1 --upload /client_files/test_file.txt --tmp /server/tmp --receive /server_files
            Sends /client_files/test_file.txt from node02 to folder /server_files at node01.

        $ weave-bdx -s node01 -c node02 -S 0 -C 1 --download /server_files/test_file.txt --tmp /server/tmp --receive /client_files
            Receives /server_files/test_file.txt from node01 at /client_files of node02.

        $ weave-bdx -s node01 -c node02 -S 1 -C 0 --upload /client_files/test_file.txt --tmp /server/tmp --receive /server_files
            Sends /client_files/test_file.txt from node02 to folder /server_files at node01.

        $ weave-bdx -s node01 -c node02 -S 1 -C 0 --download /server_files/test_file.txt --tmp /server/tmp --receive /client_files
            Receives /server_files/test_file.txt from node01 at /client_files of node02.


    Note:
        special the BDX server and client version with '-S/-C' option, and BDX-v1 would be the default version

    return:
        0   success
        1   failure

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

        self.quiet = opts["quiet"]
        self.client = opts["client"]
        self.server = opts["server"]
        self.tmp = opts["tmp"]
        self.download = opts["download"]
        self.upload = opts["upload"]
        self.receive = opts["receive"]
        self.offset = opts["offset"]
        self.length = opts["length"]
        self.tap = opts["tap"]
        self.server_version = opts["server_version"]
        self.client_version = opts["client_version"]
        self.server_faults = opts["server_faults"]
        self.client_faults = opts["client_faults"]
        self.iterations = opts["iterations"]

        self.server_process_tag = "WEAVE-BDX-SERVER" + opts["test_tag"]
        self.client_process_tag = "WEAVE-BDX-CLIENT" + opts["test_tag"]

        self.client_node_id = None
        self.server_node_id = None

        self.strace = opts["strace"]

        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":
            if self.server == "service":
                # can't use plaid when talking to an external service
                self.use_plaid = False
            else:
                self.use_plaid = self.plaid.isPlaidConfigured()


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

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

        # Check if Weave BDX server version is correct.
        if self.server_version != 0 and self.server_version != 1:
            emsg = "BDX server version is not correct."
            self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
            sys.exit(1)

        # Check if Weave BDX client version is correct.
        if self.client_version != 0 and self.client_version != 1:
            emsg = "BDX client version is not correct."
            self.logger.error("[localhost] WeaveBDX: %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] WeaveBDX: %s" % (emsg))
            sys.exit(1)

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

        # Check if Weave BDX 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)
        elif self.server == "service":
            if self.download is not None:
                self.server_ip = self.getServiceWeaveIPAddress("FileDownload")
            elif self.upload is not None:
                self.server_ip = self.getServiceWeaveIPAddress("LogUpload")
            self.server_weave_id = self.IPv6toWeaveId(self.server_ip)
            self.server_node_id = "service"

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

        if self.server_node_id == None:
            emsg = "Unknown identity of the server node."
            self.logger.error("[localhost] WeaveBDX: %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 self.server is not "service":
            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] WeaveBDX: %s" % (emsg))
            sys.exit(1)

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

        # Check tmp, upload, download, receive paths
        if self.server is not "service":
            if self.tmp == None:
                emsg = "Missing path to a temporaty directory that is used by BDX server."
                self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
                sys.exit(1)

            if not os.path.isdir(self.tmp):
                emsg = "The server BDX temp %s is not a directory." % (self.tmp)
                self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
                sys.exit(1)

        if self.receive == None:
            emsg = "Missing path to receiving directory."
            self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
            sys.exit(1)

        if not os.path.isdir(self.receive):
            emsg = "The receiving path %s is not a directory." % (self.receive)
            self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
            sys.exit(1)

        if (self.download == None and self.upload == None) or \
            (self.download != None and self.upload != None):
            emsg = "Either download or upload path must be specified."
            self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
            sys.exit(1)

        if self.offset != None:
            self.offset = str(self.offset)
            if not self.offset.isdigit():
                emsg = "File offset must be a number, not %s." % (self.offset)
                self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
                sys.exit(1)

        if self.length != None:
            self.length = str(self.length)
            if not self.length.isdigit():
                emsg = "File length must be a number, not %s." % (self.length)
                self.logger.error("[localhost] WeaveBDX: %s" % (emsg))
                sys.exit(1)

    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 __start_server_side(self):
        if self.server_version == 0:
            cmd = self.getWeaveBDXv0ServerPath()
            if not cmd:
                return;

            cmd += " -a " + self.server_ip

            if self.download != None:
                cmd += " -r " + self.download
            else:
                cmd += " -R " + self.receive

        else:
            cmd = self.getWeaveBDXServerPath()
            if not cmd:
                return

            cmd += " -a " + self.server_ip \
                + " -T " + self.tmp

            if self.download != None:
                # Client downloads file specified in self.download
                cmd += " -R " + os.path.dirname(self.download)
            else:
                cmd += " -R " + self.receive

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

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

        if self.server_faults or self.client_faults:
            cmd += " --extra-cleanup-time 10000"

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

        self.start_weave_process(self.server_node_id, cmd, self.server_process_tag, strace=self.strace, env=custom_env, sync_on_output="Weave Node ready to service events")


    def __start_client_side(self):
        if self.client_version == 0:
            cmd = self.getWeaveBDXv0ClientPath()
            if not cmd:
                return;

            cmd += " " + self.server_weave_id + "@" + self.server_ip \
                + " -a " + self.client_ip + " -R " + self.receive + " -T" \
                + " --iterations " + str(self.iterations)

            if self.download != None:
                if self.server_version == 1:
                    cmd += " -r" + " file://" + self.download
                else:
                    cmd += " -r " + self.download
            else:
                cmd += " -r " + self.upload + " -p"

        else:
            cmd = self.getWeaveBDXClientPath()
            if not cmd:
                return
            if self.server is not "service":
                cmd += " " + self.server_weave_id + "@" + self.server_ip \
                    + " -a " + self.client_ip + " -T"
            else:
                cmd += " " + self.server_weave_id + "@" + self.server_ip \
                    + " -a " + self.client_ip

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

            if self.download != None:
                if self.server_version == 1:
                    if self.server is not "service":
                        cmd += " -r" + " file://" + self.download + " -R " + self.receive + " -u "
                    else:
                        cmd +=" -r" + " weave-bdx://" + self.download + " -R " + self.receive + " -u "
                else:
                    cmd += " -r " + self.download + " -R " + self.receive
            else:
                if self.server is not "service":
                    cmd += " -r " + self.upload + " -p"
                else:
                    cmd += " -r " + self.upload + " -p -u"

        if self.offset != None:
                cmd += " -s " + self.offset

        if self.length != None:
                cmd += " -l " + self.length

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

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

        if self.server_faults or self.client_faults:
            cmd += " --extra-cleanup-time 10000"


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

        self.start_weave_process(self.client_node_id, cmd, self.client_process_tag, strace=self.strace, env=custom_env)


    def __process_results(self, client_output, server_output):
        parser_error = False
        leak_detected = False
        transfer_done = False

        parser_error, leak_detected = WeaveUtilities.scan_for_leaks_and_parser_errors(client_output)

        for line in client_output.split("\n"):
            if "WEAVE:BDX: Transfer complete!" in line:
                transfer_done = True
                break

        if self.quiet == False:
            if self.download:
                print "weave-bdx from server v%s %s (%s) to client v%s %s (%s) : " % \
                    (self.server_version, self.server_node_id, self.server_ip,
                     self.client_version, self.client_node_id, self.client_ip)
                if transfer_done:
                    print hgreen("downloaded")
                else:
                    print hred("not downloaded")
            else:
                print "weave-bdx from client %s (%s) to server %s (%s) : " % \
                    (self.client_node_id, self.client_ip,
                    self.server_node_id, self.server_ip)
                if transfer_done:
                    print hgreen("uploaded")
                else:
                    print hred("not uploaded")
            if leak_detected:
                print hred("resource leak detected in the client's ouput")
            if parser_error:
                print hred("parser error in the client's output")


        pass_test = transfer_done and not leak_detected and not parser_error

        if self.server is not "service":
            # check the server for leaks and parser errors
            parser_error, leak_detected = WeaveUtilities.scan_for_leaks_and_parser_errors(server_output)
            if self.quiet == False:
                if leak_detected:
                    print hred("resource leak detected in the server's ouput")
                if parser_error:
                    print hred("parser error in the server's output")

        pass_test = pass_test and not parser_error and not leak_detected

        return (pass_test, client_output)


    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 __stop_plaid_server(self):
        self.plaid.stopPlaidServerProcess()


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

        self.__pre_check()

        if self.server is "service":
            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)

            status, results = self.__process_results(client_output_data, '')
            # status = 0
            data = {}
            data["client_output"] = client_output_data
        else:
            if self.use_plaid:
                self.__start_plaid_server()

            self.__start_server_side()

            emsg = "WeaveBDX %s should be running." % (self.server_process_tag)
            self.logger.debug("[%s] WeaveBDX: %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()

            if self.use_plaid:
                self.__stop_plaid_server()

            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)

            status, results = self.__process_results(client_output_data, server_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] WeaveBDX: Done.")
        return ReturnMsg(status, data)

