# -*- coding: utf-8 -*-

##
# Copyright ETSI Contributors and Others.
#
# 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.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##

"""
This module contains unit tests for the OpenStack VIM connector
Run this directly with python2 or python3.
"""

import logging
import json

from osm_rovim_gcp.vimconn_gcp import vimconnector
from datetime import datetime


__author__ = "Sergio G.R."
__date__ = "$05-nov-2021 12:00:00$"


class TestGCPOperations():

    gcp_conn = None
    time_id = datetime.today().strftime('%Y%m%d%H%M%S')
    vim_id = "gcp-test-" + time_id
    vim_name = vim_id
    vm_name = "gcp-test-vm-" + time_id
    net_name = "gcp-test-net-" + time_id
    cloud_config = None
    config = {}
    credentials_file = None
    image_id = None
    image_connector_id = None
    flavor_id = None

    def setUp(
        self,
        project_name,
        region_name,
        credentials_file,
        image_id,
        image_connector_id,
        flavor_id
    ):
        self.config["project_name"] = project_name
        self.config["region_name"] = region_name
        try:
            with open(credentials_file) as file:
                self.config["credentials"] = json.load(file)
        except ValueError:
            raise Exception(
                "Not possible to read credentials JSON file %s", self.config["credentials"]
            )
        self.image_id = image_id
        self.image_connector_id = image_connector_id
        self.flavor_id = flavor_id

        # instantiate dummy VIM connector so we can test it
        self.gcp_conn = vimconnector(
            uuid=self.vim_id,
            name=self.vim_name,
            tenant_id=project_name,
            tenant_name=project_name,
            url=None,
            url_admin=None,
            user=None,
            passwd=None,
            log_level=None,
            config=self.config,
        )

    def test_networks(self):
        net_id_1 = self.gcp_conn.new_network(self.net_name, None, {"subnet_address": "10.0.0.0/25"})
        net_id_2 = self.gcp_conn.new_network(self.net_name, None, {"subnet_address": "10.9.0.0/25"})
        _ = self.gcp_conn.delete_network(net_id_1[0])
        _ = self.gcp_conn.delete_network(net_id_2[0])

    def test_vminstances_default(self):
        vm_id_1 = self.gcp_conn.new_vminstance(
            name=self.vm_name,
            description="testvm",
            start=True,
            image_id=self.image_id,
            flavor_id=self.flavor_id,
            net_list=[{"name": "default", "use": "mgmt"}],
            cloud_config=self.cloud_config,
        )
        _ = self.gcp_conn.delete_vminstance(vm_id_1[0])

    def test_vminstances_2_nets(self):
        net_id_1 = self.gcp_conn.new_network(self.net_name, None, {"subnet_address": "10.0.0.0/25"})
        net_id_2 = self.gcp_conn.new_network(self.net_name, None, {"subnet_address": "10.9.0.0/25"})

        vm_id_1 = self.gcp_conn.new_vminstance(
            name=self.vm_name,
            description="testvm",
            start=True,
            image_id=self.image_id,
            flavor_id=self.flavor_id,
            net_list=[{"net_id": net_id_1[0], "use": "mgmt"}, {"net_id": net_id_2[0], "use": "internal"}],
            cloud_config=self.cloud_config,
        )
        _ = self.gcp_conn.delete_vminstance(vm_id_1[0])

        _ = self.gcp_conn.delete_network(net_id_1[0])
        _ = self.gcp_conn.delete_network(net_id_2[0])


    def test_vminstances_image_connector_id(self):
        image_id = self.gcp_conn.get_image_list({"name": self.image_connector_id})
        vm_id_1 = self.gcp_conn.new_vminstance(
            name=self.vm_name,
            description="testvm",
            start=True,
            image_id=image_id[0].get("id"),
            flavor_id=self.flavor_id,
            net_list=[{"name": "default", "use": "mgmt"}],
            cloud_config=self.cloud_config,
        )
        _ = self.gcp_conn.delete_vminstance(vm_id_1[0])

    def test_vminstances_flavor(self):
        machine_type = self.gcp_conn.get_flavor_id_from_data(
            {'disk': 10, 'ram': 2048, 'vcpus': 1, 'extended': {'mempage-size': 'LARGE', 'numas': [{'threads': 1}]}}
        )
        vm_id_1 = self.gcp_conn.new_vminstance(
            name=self.vm_name,
            description="testvm",
            start=True,
            image_id=self.image_id,
            flavor_id=machine_type,
            net_list=[{"name": "default", "use": "mgmt"}],
            cloud_config=self.cloud_config,
        )
        _ = self.gcp_conn.delete_vminstance(vm_id_1[0])


if __name__ == "__main__":
    # Setting logging parameters:
    log_format = "%(asctime)s %(levelname)s %(name)s %(filename)s:%(lineno)s %(funcName)s(): %(message)s"
    log_formatter = logging.Formatter(log_format, datefmt="%Y-%m-%dT%H:%M:%S")
    handler = logging.StreamHandler()
    handler.setFormatter(log_formatter)
    logger = logging.getLogger("ro.vim.gcp")
    logger.setLevel(level=logging.DEBUG)
    logger.addHandler(handler)

    # Setting relevant values for the tests from environment file
    gcp_env_file = "gcp.env"

    try:
        with open(gcp_env_file) as f:
            for line in f:
                var, value = line.replace('\n', '').split("=")
                if var == "GCP_PROJECT":
                    project_name = value
                elif var == "GCP_REGION":
                    region_name = value
                elif var == "GCP_CREDENTIALS":
                    credentials_file = value
                elif var == "GCP_IMAGE":
                    image_id = value
                elif var == "GCP_IMAGE_CONNECTOR_ID":
                    image_connector_id = value
                elif var == "GCP_FLAVOR":
                    flavor_id = value
    except ValueError:
        raise Exception(
            "Wrong format of GCP test environment file"
        )

    if (
        project_name is None
        or region_name is None
        or credentials_file is None
        or image_id is None
        or image_connector_id is None
        or flavor_id is None
    ):
        raise Exception(
            "GCP test environment file must include at least GCP_PROJECT, GCP_REGION, "
            "GCP_CREDENTIALS, GCP_IMAGE, GCP_IMAGE_PATTERN and GCP_FLAVOR"
        )

    test_gcp = TestGCPOperations()
    test_gcp.setUp(
        project_name,
        region_name,
        credentials_file,
        image_id,
        image_connector_id,
        flavor_id
    )
    test_gcp.test_networks()
    test_gcp.test_vminstances_default()
    test_gcp.test_vminstances_2_nets()
    test_gcp.test_vminstances_connector_id()
    test_gcp.test_vminstances_flavor()

