
# Copyright 2020 VMware, Inc.  All rights reserved. -- VMware Confidential
# coding: utf-8

import os
import re
import psycopg2
import pwd
import grp
import logging
import subprocess

from .const import PROPERTIES_FILE, LOG_FILE
from cis.defaults import get_psql_bin
from cis.utils import  invoke_command
from cis.baseCISException import BaseInstallException

def setup_logging(otherLogger):
    f_handler = logging.FileHandler(LOG_FILE)
    f_handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(module)s:%(lineno)d:%(levelname)s: %(message)s")
    f_handler.setFormatter(formatter)
    otherLogger.addHandler(f_handler)

logger = logging.getLogger(__name__)
setup_logging(logger)

def get_db_properties():
    ''' Returns information about the database
    '''
    with open(PROPERTIES_FILE, "r") as auth_file:
      lines = auth_file.readlines()
      lines[2] = re.split(r'\W+', lines[2].strip())
      lines[3] = lines[3].strip().split("=")[1].strip()
      #  Since '=' can occur in the password line, we handle this line a bit differently
      split = lines[4].strip().find("=") + 2
      lines[4] = lines[4][split:].strip()
      dbname = lines[2][5]
      user = lines[3]
      password = lines[4]
      host = lines[2][3]
      port = lines[2][4]
      return dbname, user, password, host, port

def get_psql_connection():
   """
   Gets the psycopg2 connection and cursor objects to the database
   :return: (connection, cursor)
   :rtype: Tuple of psycopg2 objects
   """
   dbname, user, password, host, port = get_db_properties()

   PSQL_DB_CONN = psycopg2.connect(dbname=dbname, user=user, password=password, host=host, port=port)
   PSQL_DB_CURSOR = PSQL_DB_CONN.cursor()
   return (PSQL_DB_CONN, PSQL_DB_CURSOR)


def _execute_sql_file(sqlScriptPath, params=None):
    ''' Executes the given sql file in the context of the vlcm schema.
    '''
    logger.info("Executing file: %s", sqlScriptPath)
    dbname, user, password, _host, port = get_db_properties()
    var_assignment = ['-v', 'ON_ERROR_STOP=1']
    if params:
        for var_key in params:
            var_assignment.extend(['-v', '%s=%s' % (var_key, params[var_key])])

    cmd = [get_psql_bin(), '-p', port, '-U', user, '-X', '-d', dbname,
            '-f', sqlScriptPath]
    cmd.extend(var_assignment)

    logger.debug("Executing %s", cmd)
    # Extend local environment to include password
    localEnv = os.environ.copy()
    localEnv["PGPASSWORD"] = password

    process = subprocess.Popen(cmd, env=localEnv, close_fds=True,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()
    stdout = str(stdout)
    stderr = str(stderr)

    if process.returncode != 0:
        logger.error("Failed running command:\n Out: %s,\n Err: %s", stdout, stderr)
        raise BaseInstallException("Failed to execute sql command.")
    else:
        logger.debug("Done running command:\n Out: %s,\n Err: %s", stdout, stderr)



