#!/usr/bin/env python
from pathlib import Path
import os
import subprocess
from string import Template
from .command import Command
from matador.session import Session


def _command(dbms, server, port, database, user, password):
    oracle_connection = Template(
        '${user}/${password}@${server}:${port}/${database}')
    mssql_host = Template('${server}:${port}')
    subs = {
        'user': user,
        'password': password,
        'server': server,
        'port': port,
        'database': database
    }

    commands = {
        ('oracle', 'nt'): [
            'sqlplus', '-S', '-L', oracle_connection.substitute(subs)],
        ('mssql', 'posix'): [
            'fisql', '-S', mssql_host.substitute(subs),
            '-D', database, '-U', user, '-P', password],
        ('mssql', 'nt'): [
            'sqlcmd', '-S', mssql_host.substitute(subs),
            '-D', database, '-U', user, '-P', password],
    }
    commands[('oracle', 'posix')] = commands[('oracle', 'nt')]

    return commands[(dbms, os.name)]


def _sql_script(dbms, file_path):
    with file_path.open('r') as f:
        script = f.read()
        f.close()

    if dbms == 'oracle':
        script += '\nshow error'

    return script.encode('utf-8')


def run_sql_script(logger, dbms, server, port, database, user, password,
                   file_path):
    file = Path(file_path)
    message = Template(
        'Matador: Executing ${file} against ${connection} \n')
    substitutions = {
        'file': file.name,
        'connection': Session.environment['connection']
    }
    logger.info(message.substitute(substitutions))

    os.chdir(str(file.parent))

    process = subprocess.Popen(
        _command(dbms, dbms, server, port, database, user, password),
        stdin=subprocess.PIPE,
        stderr=subprocess.PIPE)
    process.stdin.write(_sql_script(dbms, file))
    process.stdin.close()
    process.wait()


class RunSqlScript(Command):

    def _add_arguments(self, parser):

        parser.add_argument(
            '-d', '--directory',
            type=str,
            required=True,
            help='Directory containing script')

        parser.add_argument(
            '-f', '--file',
            type=str,
            required=True,
            help='Script file name')

        parser.add_argument(
            '-e', '--environment',
            type=str,
            required=True,
            help='Agresso environment')

    def _execute(self):
        Session.set_environment(self.args.environment)

        file_path = os.path.join(self.args.directory, self.args.file)

        run_sql_script(
            self._logger,
            Session.environment['database']['dbms'].lower(),
            Session.environment['database']['server'],
            Session.environment['database']['port'],
            Session.environment['database']['db_name'],
            Session.credentials['user'],
            Session.credentials['password'],
            file_path)

@@ -180,52 +180,17 @@
 and(
-dbms, server, port, database, user, password
+**db_args
 ):%0A 
@@ -272,22 +272,21 @@
 ort%7D/$%7Bd
-atabas
+b_nam
 e%7D')%0A   
@@ -332,156 +332,8 @@
 t%7D')
-%0A    subs = %7B%0A        'user': user,%0A        'password': password,%0A        'server': server,%0A        'port': port,%0A        'database': database%0A    %7D
 %0A%0A  
@@ -439,19 +439,22 @@
 stitute(
-sub
+db_arg
 s)%5D,%0A   
@@ -521,35 +521,38 @@
 host.substitute(
-sub
+db_arg
 s),%0A            
@@ -562,43 +562,96 @@
 ', d
-atabase, '-U', user, '-P', password
+b_args%5B'db_name'%5D, '-U', db_args%5B'user'%5D,%0A            '-P', db_args%5B'password'%5D%0A        
 %5D,%0A 
@@ -726,19 +726,22 @@
 stitute(
-sub
+db_arg
 s),%0A    
@@ -759,43 +759,96 @@
 ', d
-atabase, '-U', user, '-P', password
+b_args%5B'db_name'%5D, '-U', db_args%5B'user'%5D,%0A            '-P', db_args%5B'password'%5D%0A        
 %5D,%0A 
@@ -939,18 +939,29 @@
 ands%5B(db
-ms
+_args%5B'dbms'%5D
 , os.nam
@@ -1206,82 +1206,28 @@
 er, 
-dbms, server, port, database, user, password,%0A                   file_path
+file_path, **db_args
 ):%0A 
@@ -1587,58 +1587,17 @@
 and(
-dbms, dbms, server, port, database, user, password
+**db_args
 ),%0A 
@@ -1692,26 +1692,37 @@
 ql_script(db
-ms
+_args%5B'dbms'%5D
 , file))%0A   
@@ -2371,17 +2371,16 @@
 onment)%0A
-%0A
         
@@ -2441,25 +2441,24 @@
 s.file)%0A
-%0A
         
 run_sql_
@@ -2453,380 +2453,132 @@
     
-run_sql_script(%0A            self._logger,%0A            Session.environment%5B'database'%5D%5B'dbms'%5D.lower(),%0A            Session.environment%5B'database'%5D%5B'server'%5D,%0A            Session.environment%5B'database'%5D%5B'port'%5D,%0A            Session.environment%5B'database'%5D%5B'db_name'%5D,%0A            Session.credentials%5B'user'%5D,%0A            Session.credentials%5B'password'%5D,%0A            file_path
+db_args = %7B**Session.environment%5B'database'%5D, **Session.credentials%7D%0A        run_sql_script(self._logger, file_path, **db_args
 )%0A

Refactor to use packed arguments