#!/usr/bin/env python

from __future__ import absolute_import
import os
import sys

import logging

from patch_task import PatchTask

__copyright__ = 'Copyright (c) 2017, 2021 VMware, Inc. All rights reserved. VMware Confidential'

"""
db_patch.py is designed for the CLS DB patch task.
"""

logger = logging.getLogger(__name__)


class DBPatchTask(PatchTask):
    def __init__(self, component_name):
        """
        Constructor of the DB patch task. Adds the necessary components to the python path

        VMWARE_PYTHON_PATH          - /usr/lib/vmware/site-packages
        VMWARE_PYTHON_MODULES_HOME  - /usr/lib/vmware/site-packages/cis

        Args:
            component_name (str): Name of the component
        """

        # This sys.path and import related code is added here, and not at the
        # standard place of __init__.py
        # The __init__.py is executed both before and after patch. This file,
        # on the other hand, is executed only after software to be patched is
        # installed. This way we make sure that imported files are Python 3
        # compliant, even when we are patching a Python 2 VC.

        sys.path.append(os.path.dirname(os.path.abspath(__file__)))
        if not os.environ['VMWARE_PYTHON_PATH'] in sys.path:
            sys.path.append(os.environ['VMWARE_PYTHON_PATH'])
            if not os.environ['VMWARE_PYTHON_MODULES_HOME'] in sys.path:
                sys.path.append(os.environ['VMWARE_PYTHON_MODULES_HOME'])

        from cis.defaults import (def_by_os, get_cis_install_dir, get_db_module_path)
        sys.path.append(get_db_module_path())  # Add dbsetup.py module in the path

        cls_install_dir = def_by_os('%s/vmware-%s' % (get_cis_install_dir(), component_name),
                                    os.path.join(get_cis_install_dir(), component_name))
        sys.path.append(cls_install_dir)
        sys.path.append(os.path.join(cls_install_dir, "install_lib"))

        from pre_install import FirstbootDbSetup
        from cis.defaults import (def_by_os, get_cis_config_dir, get_cis_install_dir)

        self.component_name = component_name
        self._db_type = FirstbootDbSetup().db_type

        self._home_dir = def_by_os(
            '%s/vmware-%s' % (get_cis_install_dir(), self.component_name),
            os.path.join(get_cis_install_dir(), self.component_name))
        logger.info("Home dir of %s: %s", self.component_name, self._home_dir)

        self._config_dir = def_by_os(
            '%s-%s' % (get_cis_config_dir(), self.component_name),
            os.path.join(get_cis_config_dir(), self.component_name))
        logger.info("Config dir of %s: %s", self.component_name, self._config_dir)

        self._db_util_path = os.path.join(self._home_dir, "install_lib")
        logger.info("DB util path of %s: %s", self.component_name, self._db_util_path)

        from install_common import get_vcdb_properties_path

        self.vcdb_properties_path = get_vcdb_properties_path()
        logger.info("VC DB property path: %s", self.vcdb_properties_path)

    def check_db_version(self):
        '''
        Gets the content library patch version. Currently, used for NDU.
        For the NDU the cl_config table must exist.
        '''
        from db_common import db_version_check
        return db_version_check(self._db_type, self._db_util_path, self._home_dir,
                                os.path.expandvars(self.vcdb_properties_path))

    def run_patch_query(self, sql_file):
        """
        Executes the content library patch query. Currently used for NDU.
        """
        from db_common import db_get_base_command
        base_cmd = db_get_base_command(self._db_type, self._db_util_path,
                                       os.path.expandvars(self.vcdb_properties_path), True)
        sql_cmd = base_cmd + [sql_file]
        error_message = "Error executing sql: %s", sql_file
        from db_common import run_db_command
        run_db_command(self._db_type, sql_cmd, log_message=error_message)

    def run(self):
        """
        Perform DB patches by running DB upgrade tasks
        """
        from db_common import initialize_database

        logger.info("Start DB patching %s for DB type: %s ...", self.component_name, self._db_type)
        initialize_database(self._db_type, self._db_util_path, self._home_dir,
                            self._config_dir, os.path.expandvars(self.vcdb_properties_path))
        logger.info("Finished DB patching %s.", self.component_name)
