"""Utilities for working with puppet tools."""

from __future__ import absolute_import
import collections
import re

_ANSI_COLOR_ESCAPE_SEQUENCE = r'\x1b[^m]*m'


def parser_errors_to_comments(errors, directory):
  """Convert errors reported by the puppet parser in Gerrit comments.

  An example of an error from the puppet parser validator looks like:
    Error: Could not parse for environment prod:
      Syntax error at ','; expected '}' at /path/to/puppet/file.pp:27

  Args:
    errors: List of stderr strings output from the pupper parser.
    directory: The directory to strip off of any filenames so file comments
        are rooted at the project directory that Gerrit expects.

  Returns:
    Dict of Gerrit comments:
      { 'filename': [{'line': '27', 'message': 'Error!'}, ...], ... }
  """

  comments = collections.defaultdict(list)
  for error in errors:
    error = re.sub(_ANSI_COLOR_ESCAPE_SEQUENCE, '', error)
    error_parts = error.split()
    error_location = error_parts[-1]  # /path/to/puppet/file.pp:27
    abs_filename, line_number = error_location.split(':')
    rel_filename_start = abs_filename.index(directory) + len(directory)
    rel_filename = abs_filename[rel_filename_start:]
    if rel_filename.startswith('/'):
      rel_filename = rel_filename[1:]

    error_parts[-1] = '{}:{}'.format(rel_filename, line_number)

    comment = {'line': line_number, 'message': ' '.join(error_parts)}
    comments[rel_filename].append(comment)

  return comments


def linter_errors_to_comments(errors, directory):
  """Convert errors reported by puppet-lint in Gerrit comments.

  Example json error:
    {
     "message": "indentation of => is not properly aligned",
     "line": 6,
     "column": 12,
     "token": "#<PuppetLint::Lexer::Token:0x00000001d885a0>",
     "indent_depth": 13,
     "newline": false,
     "newline_indent": "    ",
     "kind": "warning",
     "check": "arrow_alignment",
     "fullpath": "/abs/path/to/puppet/manifests/common.pp",
     "path": "manifests/common.pp",
     "filename": "common.pp",
     "KIND": "WARNING"
     }


  Args:
    errors: List of error dicts returned from puppet-lint with --json
    directory: The directory to strip off of any filenames so file comments
        are rooted at the project directory that Gerrit expects.

  Returns:
    Dict of Gerrit comments:
      { 'filename': [{'line': '27', 'message': 'Error!'}, ...], ... }
  """
  if not errors:
    return {}

  # puppet-lint output can wrap errors in nested lists, e.g.
  # [[error1, error2, ...]], so handle that gracefully.
  if isinstance(errors[0], list):
    errors = errors[0]

  comments = collections.defaultdict(list)
  for error in errors:
    comment = {'line': str(error['line']), 'message': error['message']}
    rel_filename_start = error['path'].index(directory) + len(directory)
    rel_filename = error['path'][rel_filename_start:]
    if rel_filename.startswith('/'):
      rel_filename = rel_filename[1:]
    comments[rel_filename].append(comment)
  return comments


def get_cron_entries(puppet_lines):
  """Pull out cron entries from a puppet file.

  A cron entry is converted into a dict, where the keys are the attributes
  and the values are the attribute values (as strings).

  In addition, the dict as a special '_line_number' attribute that records
  the line number the cron entry started at.

  Example
    # Puppet entry                      # As dict
    27: cron { 'my_cron':                   cron_entry = {
    28:  ensure => present,                    'ensure': 'present',
    29:  hour   => 2,              ---->       'hour': '2',
    30:  minute => 0,                          'minute': '0',
    31:  command => $some_script,              'command': '$some_script',
                                               '_line_number': '27',
    32: }                                   }

  Args:
   puppet_lines: List of lines from a puppet_file (e.g. from readlines()).

  Returns:
   List of dict objects representing the cron entries.
  """
  cron_entries = []
  within_cron_entry = False
  curly_brace_count = 0
  for line_number, line in enumerate(puppet_lines, start=1):
    if 'cron {' in line:
      within_cron_entry = True
      curly_brace_count = 1
      cron_entry = {'_line_number': str(line_number)}
      continue

    if not within_cron_entry:
      continue

    curly_brace_count += line.count('{') - line.count('}')
    if curly_brace_count == 0:
      within_cron_entry = False
      cron_entries.append(cron_entry)
      cron_entry = {}
      continue

    if '=>' in line:
      attribute, value = line.split('=>', 1)
      if value.rstrip().endswith(','):
        value = value.rstrip()[:-1]
      cron_entry[attribute.strip()] = value.lstrip()

  return cron_entries


def cron_errors_to_comments(errors):
  """Converts |errors| into Gerrit-style comments.

  Args:
    errors: List of (filename, cron_entry dict)
  Returns:
    Dict of Gerrit comments:
      { 'filename': [{'line': '27', 'message': 'Error!'}, ...], ... }
  """
  comments = collections.defaultdict(list)
  for puppet_file, cron_entry in errors:
    comment = {'line': cron_entry['_line_number'],
               'message': 'cron entry missing "minute" attribute.',}
    comments[puppet_file].append(comment)
  return comments


