#!/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 WeaveTunnelStart class that start Weave Tunnel
#       between border-gateway and a service.
#

import os
import sys
import time

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

import happy.HappyNodeRoute
import happy.HappyNetworkAddress

import plugin.WeaveTunnelStop as WeaveTunnelStop
from plugin.WeaveTest import WeaveTest
import plugin.WeaveUtilities as WeaveUtilities


options = {"border_gateway": None,
           "service": None,
           "tap": None,
           "primary": None,
           "backup": None,
           "customized_tunnel_port": None,
           "service_dir": False,
           "skip_service_end": False,
           "tunnel_log": True,
           "case": False,
           "service_dir_server": None,
           "service_process_tag": "WEAVE-SERVICE-TUNNEL",
           "gateway_process_tag": "WEAVE-GATEWAY-TUNNEL",
           "case_cert_path": None,
           "case_key_path": None,
           "test_tag": "",
           "iterations": 1,
           "gateway_faults": None,
           "service_faults": None,
           "strace": False,
           "sync_on_gateway_output": "",
           "sync_on_service_output": "",
           "product_id": "12", # kNestWeaveProduct_Flintstone
           "plaid_gateway_env": {},
           "plaid_service_env": {}
           }


def option():
    return options.copy()


class WeaveTunnelStart(HappyNode, HappyNetwork, WeaveTest):
    """
    weave-tunnel-start start a tunnel between border-gateway and a service

    weave-tunnel-start [-h --help] [-q --quiet] [-b --border_gateway <NODE_ID>]
        [-s --service <NODE_ID> | <IP_ADDR>] [-p --tap <TAP_INTERFACE>] [-P --primary <PRIMARY_INTERFACE>] [-B --backup <BACKUP_INTERFACE>]
        [-d --service_dir] [-i --service_dir_server <SERVICE_HOST>] [-C --case] [-E --case_cert_path <path>] [-T --case_key_path <path>]

    Example:
    $ weave-tunnel-start node01 node02
        Start weave tunnel between border-gateway node01 and service node02.

    $ weave-tunnel-start node01 184.72.129.8
        Start weave tunnel between border-gateway node01 and a node with an IP address 184.72.129.8.

    $ weave-tunnel-start --border_gateway node01 --service_dir --service_dir_server  "frontdoor.integration.nestlabs.com" --case --case_cert_path path --case_key_path path
        Start weave tunnel with case encryption between border-gateway node01 and a node with the service loopup directory frontdoor.integration.nestlabs.com.

    $ weave-tunnel-start --border_gateway node01 --service 184.72.129.8 -P wlan0 -B cellular0
        Start weave tunnel between border-gateway node01 and a node with an IP address 184.72.129.8, the primary tunnel go through wlan0, the backup tunnel
        go through cellular0

    return:
        0    success
        1    fail
    """

    def __init__(self, opts = options):
        HappyNode.__init__(self)
        HappyNetwork.__init__(self)
        WeaveTest.__init__(self)
        self.__dict__.update(opts)
        emsg = "starting with opts: %s" %opts
        self.logger.debug("[localhost] WeaveTunnelStart: %s" %emsg)

        self.gateway_process_tag += self.test_tag
        self.service_process_tag += self.test_tag

    def __stopExistingTunnel(self):
        options = WeaveTunnelStop.option()
        options["border_gateway"] = self.border_gateway
        options["service"] = self.service

        stopTunnel = WeaveTunnelStop.WeaveTunnelStop(options)
        stopTunnel.run()

        self.readState()


    def __pre_check(self):
        # Check if border-gateway node was given
        if not self.border_gateway:
            emsg = "Border-gateway node id not specified."
            self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
            self.exit()

        if not self._nodeExists(self.border_gateway):
            emsg = "Border-gateway node %s does not exist." % (self.border_gateway)
            self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
            self.exit()

        # Check if service node was given in the environment
        if not self.service and not self.service_dir:
            if "weave_service_address" in os.environ.keys():
                self.service = os.environ['weave_service_address']
                emsg = "Found weave_service_address %s." % (self.service)
                self.logger.debug("[localhost] Weave: %s" % (emsg))

        if not self.service and self.service_dir:
            if self.service_dir_server:
                self.skip_service_end = True
                self.logger.debug("[localhost] WeaveTunnelStart against tier %s." % self.service_dir_server)
            else:
                if "weave_service_address" in os.environ.keys():
                    self.skip_service_end = True
                    self.service_dir_server = os.environ['weave_service_address']
                    self.logger.debug("[localhost] WeaveTunnelStart against tier %s." % self.service_dir_server)
                else:
                    # Check if service node was given
                    emsg = "Service node id (or IP address or service directory) not specified."
                    self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
                    self.exit()

        if self.service:
            # If service is a domain name, convert it to IP
            if self.isDomainName(self.service):
                ip = self.getHostByName(self.service)
                self.service = ip

            if not self.isIpAddress(self.service) and not self._nodeExists(self.service):
                emsg = "Service node %s does not exist." % (self.service)
                self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
                self.exit()

            if self.isIpAddress(self.service):
                self.service_ip = self.service
                self.skip_service_end = True
            else:
                self.service_ip = self.getNodePublicIPv4Address(self.service)

            if self.service_ip == None:
                emsg = "Could not find IP address of the service node."
                self.logger.error("[localhost] WeaveTunnel: %s" % (emsg))
                self.exit()

        self.fabric_id = self.getFabricId()

        # Check if there is no fabric
        if self.fabric_id == None:
            emsg = "There is not Weave fabric."
            self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
            self.exit()

        # Check if there is a tunnel
        if self.getTunnelServiceNodeId() or self.getTunnelServiceDir():
            emsg = "There already exist a Weave tunnel."
            self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
            self.__stopExistingTunnel()


        self.service_weave_id = self.getServiceWeaveID("Tunnel")
        self.gateway_weave_id = self.getWeaveNodeID(self.border_gateway)

        if self.service_weave_id == None:
            emsg = "Could not find Weave node ID of the service node."
            self.logger.error("[localhost] WeaveTunnel: %s" % (emsg))
            self.exit()

        if self.gateway_weave_id == None:
            emsg = "Could not find Weave node ID of the border-gateway node."
            self.logger.error("[localhost] WeaveTunnel: %s" % (emsg))
            self.exit()


    def __start_tunnel_at_service(self):
        cmd = self.getWeaveTunnelServicePath()
        if not cmd:
            return

        cmd += " --node-id " + str(self.service_weave_id)
        cmd += " --fabric-id " + str(self.fabric_id)

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

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

        cmd += " --debug-resource-usage"
        cmd += " --print-fault-counters"

        cmd = self.runAsRoot(cmd)
        self.start_weave_process(self.service, cmd, self.service_process_tag, strace=self.strace, sync_on_output=self.sync_on_service_output, env=self.plaid_service_env)

        max_wait_time = 40

        while not self._nodeInterfaceExists(self.service_tun, self.service):
            time.sleep(0.1)
            max_wait_time -= 1

            if max_wait_time <= 0:
                emsg = "Service-side tunnel interface %s was not created." % (self.service_tun)
                self.logger.error("[%s] WeaveTunnel: %s" % (self.service, emsg))
                self.exit()

            if (max_wait_time) % 10 == 0:
                emsg = "Waiting for interface %s to be created." % (self.service_tun)
                self.logger.debug("[%s] WeaveTunnel: %s" % (self.service, emsg))

        with self.getStateLockManager():
            self.readState()

            new_node_interface = {}
            new_node_interface["link"] = None
            new_node_interface["type"] = self.network_type["tun"]
            new_node_interface["ip"] = {}
            self.setNodeInterface(self.service, self.service_tun, new_node_interface)

            self.writeState()


    def __assing_tunnel_endpoint_ula_at_service(self):
        addr = self.getServiceWeaveIPAddress("Tunnel", self.service)

        options = happy.HappyNodeAddress.option()
        options["node_id"] = self.service
        options["interface"] = self.service_tun
        options["address"] = addr
        options["add"] = True

        addAddr = happy.HappyNodeAddress.HappyNodeAddress(options)
        addAddr.run()


    def __start_tunnel_at_gateway(self):
        cmd = self.getWeaveTunnelBorderGatewayPath()
        if not cmd:
            return

        cmd += " --node-id " + self.gateway_weave_id
        cmd += " --fabric-id " + str(self.fabric_id)

        if self.tap:
            cmd += " --interface " + self.tap
        if self.primary:
            cmd += " --primary-intf " + self.primary
        if self.backup:
            cmd += " --backup-intf " + self.backup + " --enable-backup "
        if self.tunnel_log:
            cmd += " --tunnel-log"
        if self.product_id:
            cmd += " --product-id " + self.product_id
        if self.case:
            cmd += ' --case'
            if not self.case_cert_path == 'default':
                self.cert_file = self.case_cert_path if self.case_cert_path else os.path.join(self.main_conf['log_directory'], self.gateway_weave_id.upper() + '-cert.weave-b64')
                self.key_file = self.case_key_path if self.case_key_path else os.path.join(self.main_conf['log_directory'], self.gateway_weave_id.upper() + '-key.weave-b64')
                cmd += ' --node-cert ' + self.cert_file + ' --node-key ' + self.key_file

            if self.service_dir:
                cmd += " --service-dir " + str(self.service_weave_id) + ' --service-dir-server ' + self.service_dir_server
            else:
                cmd += " --connect-to " + self.service_ip + " " + str(self.service_weave_id)
        elif self.service:
            if self.customized_tunnel_port:
                self.service_ip = self.service_ip + ":%d" % self.customized_tunnel_port
            cmd += " --connect-to " + self.service_ip + " " + str(self.service_weave_id)

        # fault-injection related
        cmd += " --debug-resource-usage"
        cmd += " --print-fault-counters"

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

        cmd = self.runAsRoot(cmd)
        self.start_weave_process(self.border_gateway, cmd, self.gateway_process_tag, strace=self.strace, sync_on_output=self.sync_on_gateway_output, env=self.plaid_gateway_env)


    def __post_check(self):
        tries = 100
        while not self._nodeInterfaceExists(self.gateway_tun, self.border_gateway):
            self.logger.debug("[localhost] WeaveTunnelStart: sleeping in __post_check")
            time.sleep(1)
            tries -= 1
            if tries < 0:
                emsg = "Tunnel interface %s cannot be found at node %s." % (self.gateway_tun, self.border_gateway)
                self.logger.error("[localhost] WeaveTunnelStart: %s" % (emsg))
                self.exit()


    def __add_tunnel_state(self):
        new_tunnel = {}
        new_tunnel["gateway"] = self.border_gateway
        new_tunnel["service"] = self.service
        new_tunnel["service_dir"] = self.service_dir_server
        self.setTunnel(new_tunnel)


    def __add_tunnel_route(self):
        self.global_prefix = self.getFabricGlobalPrefix()

        options = happy.HappyNodeRoute.option()
        options["node_id"] = self.border_gateway
        options["to"] = self.global_prefix
        options["via"] = self.gateway_tun
        options["prefix"] = self.global_prefix
        options["add"] = True

        self.logger.debug("[localhost] WeaveTunnelStart: adding route with options: " + str(options) )
        weaveServiceRoute = happy.HappyNodeRoute.HappyNodeRoute(options)
        weaveServiceRoute.start()


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

        with self.getStateLockManager():
            self.__pre_check()

        if not self.skip_service_end:
            self.__start_tunnel_at_service()
            self.__assing_tunnel_endpoint_ula_at_service()

        self.__start_tunnel_at_gateway()

        with self.getStateLockManager():
            self.readState()

            self.__post_check()

            self.__add_tunnel_state()

            self.writeState()

        self.__add_tunnel_route()

        data = {}

        gateway_output_value, gateway_output_data = \
            self.get_test_output(self.border_gateway, self.gateway_process_tag, quiet=True)
        if self.strace:
            gateway_strace_value, gateway_strace_data = \
                self.get_test_strace(self.border_gateway, self.gateway_process_tag)
            data["gateway_strace"] = gateway_strace_data

        if self.skip_service_end:
            service_output_data = ""
            service_strace_data = ""
            service_output_value = 0
        else:
            service_output_value, service_output_data = \
                self.get_test_output(self.service, self.service_process_tag, quiet=True)
            if self.strace:
                service_strace_value, service_strace_data = \
                    self.get_test_strace(self.service, self.service_process_tag)
                data["service_strace"] = service_strace_data

        data["gateway_output"] = gateway_output_data
        data["service_output"] = service_output_data
        result = gateway_output_value or service_output_value  # 0 == success, hence 'or'

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

