#! /usr/bin/python

import os
import requests
import time
from vcpecommon import *
from datetime import datetime
import soutils
import logging
import preload
import json


class CustomService:
    def __init__(self, vcpecommon):
        self.logger = logging.getLogger(__name__)
        self.vcpecommon = vcpecommon

    # delete all vgw stacks
    def del_all_vgw_stacks(self, keyword):
        param = ' '.join([k + ' ' + v for k, v in self.vcpecommon.cloud.items()])
        openstackcmd = 'openstack ' + param + ' '

        stacks = os.popen(openstackcmd + 'stack list').read()
        found = False
        for stack_description in stacks.split('\n'):
            if keyword in stack_description:
                found = True
                stack_name = stack_description.split('|')[2].strip()
                cmd = openstackcmd + 'stack delete -y ' + stack_name
                self.logger.info('Deleting ' + stack_name)
                os.popen(cmd)

        if not found:
            self.logger.info('No vGW stack to delete')

    # clean up SDNC
    def clean_up_sdnc(self):
        items = ['tunnelxconn-allotted-resources', 'brg-allotted-resources']
        for res in items:
            self.logger.info('Cleaning up ' + res + ' from SDNC')
            requests.delete(self.vcpecommon.sdnc_ar_cleanup_url + res, auth=self.vcpecommon.sdnc_userpass)

    def print_success_info(self, print_instructions=True, nodes=None):
        if not nodes:
            nodes = ['brg', 'mux', 'gw', 'web']
        ip_dict = self.vcpecommon.get_vm_ip(nodes, self.vcpecommon.external_net_addr,
                                            self.vcpecommon.external_net_prefix_len)

        print(json.dumps(ip_dict, indent=4, sort_keys=True))
        for node in ['brg', 'mux']:
            print('VxLAN config in {0}:'.format(node))
            self.vcpecommon.get_vxlan_interfaces(ip_dict[node], print_info=True)

        print(json.dumps(ip_dict, indent=4, sort_keys=True))

        if print_instructions:
            print('----------------------------------------------------------------------------')
            print('Custom service created successfully. See above for VxLAN configuration info.')
            print('To test data plane connectivity, following the steps below.')
            print(' 1. ssh to vGW at {0}'.format(ip_dict['gw']))
            print(' 2. Restart DHCP: systemctl restart isc-dhcp-server')
            print(' 3. ssh to vBRG at {0}'.format(ip_dict['brg']))
            print(' 4. Get IP from vGW: dhclient lstack')
            print(' 5. Add route to Internet: ip route add 10.2.0.0/24 via 192.168.1.254 dev lstack')
            print(' 6. ping the web server: ping {0}'.format('10.2.0.10'))
            print(' 7. wget http://{0}'.format('10.2.0.10'))

    def create_custom_service(self, csar_file, vgw_template_file, vgw_gra_template_file, preload_dict=None):
        name_suffix = datetime.now().strftime('%Y%m%d%H%M')
        if self.vcpecommon.oom_mode:
            brg_mac = str(raw_input("Enter the BRG MAC address: "))
        else:
            brg_mac = self.vcpecommon.get_brg_mac_from_sdnc()
        # get name index
        self.vgw_vfmod_name_index= self.vcpecommon.load_object(self.vcpecommon.vgw_vfmod_name_index_file)
        self.vgw_vfmod_name_index=self.vgw_vfmod_name_index + 1
        self.save_object(vgw_vfmod_name_index,self.vcpecommon.vgw_vfmod_name_index_file)
        # preload vGW
        if preload_dict:
            preloader = preload.Preload(self.vcpecommon)
            parameters_to_change = ['vgw_private_ip_0', 'vgw_private_ip_1', 'vgw_private_ip_2','vg_vgmux_tunnel_vni']
            self.vcpecommon.increase_ip_address_or_vni_in_template(vgw_template_file, parameters_to_change)
            preloader.preload_vgw(vgw_template_file, brg_mac, preload_dict, name_suffix)
            # preload vGW-GRA
            preloader.preload_vgw_gra(vgw_gra_template_file, brg_mac, preload_dict, name_suffix, vgw_vfmod_name_index)

        # create service
        so = soutils.SoUtils(self.vcpecommon, 'v5')
        if so.create_custom_service(csar_file, brg_mac, name_suffix):
            self.print_success_info()
