import logging
log = logging.getLogger('fabric.fabalicious.scripts')

from base import BaseMethod
from fabric.api import *
from fabric.contrib.files import exists
from fabric.network import *
from fabric.context_managers import settings as _settings
from lib import configuration
import re, copy

class ScriptMethod(BaseMethod):
  @staticmethod
  def supports(methodName):
    return methodName == 'script'

  @staticmethod
  def getGlobalSettings():
    return {
      'scripts': {},
      'executables': {}
    }

  def printReplacements(self, replacements):

    for key in sorted(replacements.keys()):
      value = replacements[key]
      print "{key:<40}  |  {value}".format(key = key, value=value)

  def cd(self, folder, runLocally):
    if runLocally:
      return lcd(folder)
    else:
      return cd(folder)

  def runScriptImpl(self, rootFolder, commands, config, runLocally, callbacks= {}, environment = {}, replacements = {}):

    pattern = re.compile('\%(\S*)\%')
    state = {
      'warnOnly': False,
      'config': config,
      'return_code': 0,
      'runLocally': runLocally
    }

    # preflight
    ok = True
    for line in commands:
      if pattern.search(line) != None:
        log.error('Found replacement-pattern in script-line "%s", aborting ...' % line)
        ok = False

    for key in environment:
      if pattern.search(environment[key]) != None:
        log.error('Found replacement-pattern in environment "%s:%s", aborting ...' % (key, environment[key]))
        ok = False

    if not ok:
      self.printReplacements(replacements)
      exit(1)

    saved_output_prefix = env.output_prefix
    env.output_prefix = False

    for line in commands:
      with self.cd(rootFolder, runLocally), shell_env(**environment), hide('running'), show('output'):
        handled = False
        start_p = line.find('(')
        end_p = line.rfind(')')

        if start_p >= 0 and end_p > 0:
          func_name = line[0:start_p]

          if func_name in callbacks:
            arguments = False
            func_args = line[start_p+1: end_p]
            if func_args.strip() != '':
              arguments = func_args.split(',')
              arguments = map(lambda x: x.strip(), arguments)

            log.debug('Executing "%s"' % func_name)
            if arguments:
              callbacks[func_name](state, *arguments)
            else:
              callbacks[func_name](state)
            handled = True

        if not handled:
          line = self.expandCommand(line)