# 
# Copyright 2016-present Ciena Corporation
#
# 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.
#
import os, sys
import json
import platform
import subprocess
from apiclient.maas_client import MAASOAuth, MAASDispatcher, MAASClient
from paramiko import SSHClient, WarningPolicy, AutoAddPolicy
from CordTestServer import CORD_TEST_HOST

class FabricMAAS(object):
    head_node = os.getenv('HEAD_NODE', CORD_TEST_HOST)
    maas_url = 'http://{}/MAAS/api/1.0/'.format(head_node)

    def __init__(self, api_key = None, url = maas_url):
        if api_key == None:
            self.api_key = self.get_api_key()
        else:
            self.api_key = api_key
        self.auth = MAASOAuth(*self.api_key.split(':'))
        self.url = url
        self.client = MAASClient(self.auth, MAASDispatcher(), self.url)

    @classmethod
    def get_api_key(cls):
        api_key = os.getenv('MAAS_API_KEY', None)
        if api_key:
            return api_key
        cmd = ['maas-region-admin', 'apikey', '--username=cord']
        try:
            p = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        except:
            return 'UNKNOWN'
        out, err = p.communicate()
        if err:
            raise Exception('Cannot get api key for MAAS')
        return out.strip()

    def get_node_list(self):
        nodes = self.client.get(u'nodes/', 'list').read()
        node_list = json.loads(nodes)
        hosts = [ self.head_node ] +  map(lambda n: n['hostname'], node_list)
        return hosts

class Fabric(object):
    entropy = 1
    simulation = False
    def __init__(self, node_list, user = 'ubuntu', passwd = 'ubuntu', key_file = None, verbose = False):
        self.cur_node = None
        if Fabric.simulation:
            self.cur_node = FabricMAAS.head_node
        self.node_list = node_list
        self.user = user
        self.passwd = passwd
        self.key_file = key_file
        self.verbose = verbose
        self.client = SSHClient()
        self.client.load_system_host_keys()
        self.client.set_missing_host_key_policy(AutoAddPolicy())

    def run_cmd(self, node, neighbor, cmd, simulation = False):
        if simulation is True:
            Fabric.entropy = Fabric.entropy ^ 1
            return bool(Fabric.entropy)
        if node == self.cur_node:
            res = os.system(cmd)
            return res == 0
        try:
            self.client.connect(node, username = self.user, key_filename = self.key_file, timeout = 5)
        except:
            print('Unable to ssh to node %s for neighbor %s' %(node, neighbor))
            return False
        channel = self.client.get_transport().open_session()
        channel.exec_command(cmd)
        status = channel.recv_exit_status()
        channel.close()
        if self.verbose:
            print('Cmd %s returned with status %d on node %s for neighbor %s' %(cmd, status, node, neighbor))
        return status == 0

    def ping_neighbor(self, node, neighbor):
        cmd = 'ping -c 1 -w 2 {}'.format(neighbor)
        return self.run_cmd(node, neighbor, cmd, Fabric.simulation)

    def ping_neighbors(self):
        result_map = []
        for n in self.node_list:
            for adj in self.node_list:
                if adj == n:
                    continue
                res = self.ping_neighbor(n, adj)
                result_map.append((n,adj,res))

        ##report
        if self.verbose:
            for node, neighbor, res in result_map:
                print('Ping from node %s to neighbor %s returned %s\n' %(node, neighbor, res))

        failed_nodes = filter(lambda f: f[2] == False, result_map)
        return failed_nodes

if __name__ == '__main__':
    if len(sys.argv) > 1:
        nodes_file = sys.argv[1]
        with open(nodes_file, 'r') as fd:
            nodes = json.load(fd)
        node_list = nodes['node_list']
    else:
        m = FabricMAAS()
        node_list = m.get_node_list()
        print('Node list: %s' %node_list)
    Fabric.simulation = True
    fab = Fabric(node_list, verbose = False)
    failed_nodes = fab.ping_neighbors()
    if failed_nodes:
        print('Failed nodes: %s' %failed_nodes)
        for node, neighbor, _ in failed_nodes:
            print('Ping from node %s to neighbor %s Failed' %(node, neighbor))
    else:
        print('Fabric test between nodes %s is successful' %node_list)
