#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Extract eclass variable names into Haskell list format."""

from __future__ import print_function

import datetime
import os
import re
import sys
import textwrap

# Matches a line that declares a variable in an eclass.
VAR_RE = re.compile(r'@(?:ECLASS-)?VARIABLE:\s*(\w+)$')

# Matches a line that declares inheritance.
INHERIT_RE = re.compile(r'^[^#]*\binherit((?:\s+[\w-]+)+)$')

VAR_FILE_HEADER = """module ShellCheck.PortageAutoInternalVariables (
  portageAutoInternalVariables
  ) where

-- This file contains the variables generated by
-- third_party/chromiumos-overlay/dev-util/shellcheck/files/get_vars.py"""

PORTAGE_AUTO_VAR_NAME = 'portageAutoInternalVariables'


class Eclass:
  """Container for eclass information"""

  def __init__(self, name, eclass_vars, inheritances):
    self.name = name
    self.vars = eclass_vars
    self.inheritances = inheritances

  def calculate_eclass_vars(self, eclasses):
    while self.inheritances:
      name = self.inheritances.pop()
      try:
        sub_eclass = eclasses[name]
        new_vars = sub_eclass.calculate_eclass_vars(eclasses).vars
        self.vars = self.vars.union(new_vars)
      except Exception:
        pass
    return self


def print_var_list(eclass, eclass_vars):
  var_list = ' '.join(['"%s",' % v for v in sorted(eclass_vars)])
  print('    -- %s\n%s' %
        (eclass,
         textwrap.fill(
             var_list, 80, initial_indent='    ', subsequent_indent='    ')))


def process_file(eclass_path):
  eclass_name = os.path.splitext(os.path.basename(eclass_path))[0]
  with open(eclass_path, 'r') as f:
    eclass_vars = set()
    eclass_inheritances = set()
    for line in f:
      line = line.strip()
      if not line:
        continue
      while line[-1] == '\\':
        line = line[:-1] + next(f).strip()
      match = VAR_RE.search(line)
      if match:
        var_name = match.group(1)
        eclass_vars.add(var_name.strip())
      else:
        match = INHERIT_RE.search(line)
        if match:
          for inheritance in re.split(r'\s+', match.group(1)):
            if inheritance.strip():
              eclass_inheritances.add(inheritance.strip())

    return Eclass(eclass_name, eclass_vars, eclass_inheritances)


def format_eclasses_as_haskell_map(eclasses):
  map_entries = []
  join_string = '", "'
  for value in sorted(eclasses, key=(lambda x: x.name)):
    if value.vars:
      var_list_string = f'"{join_string.join(sorted(list(value.vars)))}"'
      map_entries.append(
          textwrap.fill(
              f'("{value.name}", [{var_list_string}])',
              80,
              initial_indent='    ',
              subsequent_indent='    '))
  return_string = ',\n\n'.join(map_entries)
  return_string = f"""    Data.Map.fromList
    [
{return_string}
    ]"""
  return f"""{VAR_FILE_HEADER}\n\n
-- Last Generated: {datetime.datetime.now().strftime("%x")}

import qualified Data.Map

{PORTAGE_AUTO_VAR_NAME} =
{return_string}"""


def main(argv):
  eclasses = {}
  for path in sorted(argv, key=os.path.basename):
    if not path.endswith('.eclass'):
      continue

    new_eclass = process_file(path)
    eclasses[new_eclass.name] = new_eclass
  eclasses_list = [
      value.calculate_eclass_vars(eclasses) for key, value in eclasses.items()
  ]
  print(format_eclasses_as_haskell_map(eclasses_list))


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
