#!/usr/bin/python
#

# Copyright (C) 2011, 2012, 2013 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

"""Script for converting Python constants to Haskell code fragments.

"""

import re
import types

from ganeti import _autoconf
from ganeti import compat
from ganeti import constants
from ganeti import errors
from ganeti import luxi
from ganeti import opcodes
from ganeti import qlang
from ganeti import jstore


#: Constant name regex
CONSTANT_RE = re.compile("^[A-Z][A-Z0-9_-]+$")

#: Private name regex
PRIVATE_RE = re.compile("^__.+__$")

#: The type of regex objects
RE_TYPE = type(CONSTANT_RE)

#: Keys which do not declare a value (manually maintained). By adding
# values here, we can make more lists use the actual names; otherwise
# we'll have (e.g.) both DEFAULT_ENABLED_HYPERVISOR and HT_XEN_PVM
# declare the same value, and thus the list of valid hypervisors will
# have strings instead of easily looked-up names.
IGNORED_DECL_NAMES = ["DEFAULT_ENABLED_HYPERVISOR"]


def NameRules(name):
  """Converts the upper-cased Python name to Haskell camelCase.

  """
  name = name.replace("-", "_")
  elems = name.split("_")
  return elems[0].lower() + "".join(e.capitalize() for e in elems[1:])


def StringValueRules(value):
  """Converts a string value from Python to Haskell.

  """
  value = value.encode("string_escape") # escapes backslashes
  value = value.replace("\"", "\\\"")
  return value


def DictKeyName(dict_name, key_name):
  """Converts a dict plus key name to a full name.

  """
  return"%s_%s" % (dict_name, str(key_name).upper())


def HaskellTypeVal(value):
  """Returns the Haskell type and value for a Python value.

  Note that this only work for 'plain' Python types.

  @returns: (string, string) or None, if we can't determine the type.

  """
  if isinstance(value, basestring):
    return ("String", "\"%s\"" % StringValueRules(value))
  elif isinstance(value, bool):
    return ("Bool", "%s" % value)
  elif isinstance(value, int):
    return ("Int", "%d" % value)
  elif isinstance(value, long):
    return ("Integer", "%d" % value)
  elif isinstance(value, float):
    return ("Double", "%f" % value)
  else:
    return None


def IdentifyOrigin(all_items, value):
  """Tries to identify a constant name from a constant's value.

  This uses a simple algorithm: is there a constant (and only one)
  with the same value? If so, then it returns that constants' name.

  @note: it is recommended to use this only for tuples/lists/sets, and
      not for individual (top-level) values
  @param all_items: a dictionary of name/values for the current module
  @param value: the value for which we try to find an origin

  """
  found = [name for (name, v) in all_items.items()
           if v is value and name not in IGNORED_DECL_NAMES]
  if len(found) == 1:
    return found[0]
  else:
    return None


def FormatListElems(all_items, pfx_name, ovals, tvals):
  """Formats a list's elements.

  This formats the elements as either values or, if we find all
  origins, as names.

  @param all_items: a dictionary of name/values for the current module
  @param pfx_name: the prefix name currently used
  @param ovals: the list of actual (Python) values
  @param tvals: the list of values we want to format in the Haskell form

  """
  origins = [IdentifyOrigin(all_items, v) for v in ovals]
  if compat.all(x is not None for x in origins):
    values = [NameRules(pfx_name + origin) for origin in origins]
  else:
    values = tvals
  return ", ".join(values)


def FormatDict(all_items, pfx_name, py_name, hs_name, mydict):
  """Converts a dictionary to a Haskell association list ([(k, v)]),
  if possible.

  @param all_items: a dictionary of name/values for the current module
  @param pfx_name: the prefix name currently used
  @param py_name: the Python name
  @param hs_name: the Haskell name
  @param mydict: a dictonary, unknown yet if homogenous or not

  """
  # need this for ordering
  orig_list = mydict.items()
  list_form = [(HaskellTypeVal(k), HaskellTypeVal(v)) for k, v in orig_list]
  if compat.any(v is None or k is None for k, v in list_form):
    # type not known
    return []
  all_keys = [k for k, _ in list_form]
  all_vals = [v for _, v in list_form]
  key_types = set(k[0] for k in all_keys)
  val_types = set(v[0] for v in all_vals)
  if not(len(key_types) == 1 and len(val_types) == 1):
    # multiple types
    return []
  # record the key and value Haskell types
  key_type = key_types.pop()
  val_type = val_types.pop()

  # now try to find names for the keys, instead of raw values
  key_origins = [IdentifyOrigin(all_items, k) for k, _ in orig_list]
  if compat.all(x is not None for x in key_origins):
    key_v = [NameRules(pfx_name + origin) for origin in key_origins]
  else:
    key_v = [k[1] for k in all_keys]
  # ... and for values
  val_origins = [IdentifyOrigin(all_items, v) for _, v in orig_list]
  if compat.all(x is not None for x in val_origins):
    val_v = [NameRules(pfx_name + origin) for origin in val_origins]
  else:
    val_v = [v[1] for v in all_vals]

  # finally generate the output
  kv_pairs = ["(%s, %s)" % (k, v) for k, v in zip(key_v, val_v)]
  return ["-- | Converted from Python dictionary @%s@" % py_name,
          "%s :: [(%s, %s)]" % (hs_name, key_type, val_type),
          "%s = [%s]" % (hs_name, ", ".join(kv_pairs)),
          ]


def ConvertVariable(prefix, name, value, all_items):
  """Converts a given variable to Haskell code.

  @param prefix: a prefix for the Haskell name (useful for module
      identification)
  @param name: the Python name
  @param value: the value
  @param all_items: a dictionary of name/value for the module being
      processed
  @return: a list of Haskell code lines

  """
  lines = []
  if prefix:
    pfx_name = prefix + "_"
    fqn = prefix + "." + name
  else:
    pfx_name = ""
    fqn = name
  hs_name = NameRules(pfx_name + name)
  hs_typeval = HaskellTypeVal(value)
  if (isinstance(value, types.ModuleType) or callable(value) or
      PRIVATE_RE.match(name)):
    # no sense in marking these, as we don't _want_ to convert them; the
    # message in the next if block is for datatypes we don't _know_
    # (yet) how to convert
    pass
  elif not CONSTANT_RE.match(name):
    lines.append("-- Skipped %s %s, not constant" % (fqn, type(value)))
  elif hs_typeval is not None:
    # this is a simple value
    (hs_type, hs_val) = hs_typeval
    lines.append("-- | Converted from Python constant @%s@" % fqn)
    lines.append("%s :: %s" % (hs_name, hs_type))
    lines.append("%s = %s" % (hs_name, hs_val))
  elif isinstance(value, dict):
    if value:
      lines.append("-- Following lines come from dictionary %s" % fqn)
      # try to build a real map here, if all keys have same type, and
      # all values too (i.e. we have a homogeneous dictionary)
      lines.extend(FormatDict(all_items, pfx_name, fqn, hs_name, value))
      # and now create individual names
      for k in sorted(value.keys()):
        lines.extend(ConvertVariable(prefix, DictKeyName(name, k),
                                     value[k], all_items))
  elif isinstance(value, tuple):
    tvs = [HaskellTypeVal(elem) for elem in value]
    # Custom rule for special cluster verify error tuples
    if name.startswith("CV_E") and len(value) == 3 and tvs[1][0] is not None:
      cv_ename = hs_name + "Code"
      lines.append("-- | Special cluster verify code %s" % name)
      lines.append("%s :: %s" % (cv_ename, tvs[1][0]))
      lines.append("%s = %s" % (cv_ename, tvs[1][1]))
      lines.append("")
    if compat.all(e is not None for e in tvs):
      ttypes = ", ".join(e[0] for e in tvs)
      tvals = FormatListElems(all_items, pfx_name, value, [e[1] for e in tvs])
      lines.append("-- | Converted from Python tuple @%s@" % fqn)
      lines.append("%s :: (%s)" % (hs_name, ttypes))
      lines.append("%s = (%s)" % (hs_name, tvals))
    else:
      lines.append("-- Skipped tuple %s, cannot convert all elements" % fqn)
  elif isinstance(value, (list, set, frozenset)):
    # Lists and frozensets are handled the same in Haskell: as lists,
    # since lists are immutable and we don't need for constants the
    # high-speed of an actual Set type. However, we can only convert
    # them if they have the same type for all elements (which is a
    # normal expectation for constants, our code should be well
    # behaved); note that this is different from the tuples case,
    # where we always (for some values of always) can convert
    tvs = [HaskellTypeVal(elem) for elem in value]
    if compat.all(e is not None for e in tvs):
      ttypes, tvals = zip(*tvs)
      uniq_types = set(ttypes)
      if len(uniq_types) == 1:
        values = FormatListElems(all_items, pfx_name, value, tvals)
        lines.append("-- | Converted from Python list or set @%s@" % fqn)
        lines.append("%s :: [%s]" % (hs_name, uniq_types.pop()))
        lines.append("%s = [%s]" % (hs_name, values))
      else:
        lines.append("-- | Skipped list/set %s, is not homogeneous" % fqn)
    else:
      lines.append("-- | Skipped list/set %s, cannot convert all elems" % fqn)
  elif isinstance(value, RE_TYPE):
    tvs = HaskellTypeVal(value.pattern)
    assert tvs is not None
    lines.append("-- | Converted from Python RE object @%s@" % fqn)
    lines.append("%s :: %s" % (hs_name, tvs[0]))
    lines.append("%s = %s" % (hs_name, tvs[1]))
  else:
    lines.append("-- Skipped %s, %s not handled" % (fqn, type(value)))
  return lines


def Convert(module, prefix):
  """Converts the constants to Haskell.

  """
  lines = [""]

  all_items = dict((name, getattr(module, name)) for name in dir(module))

  for name in sorted(all_items.keys()):
    value = all_items[name]
    new_lines = ConvertVariable(prefix, name, value, all_items)
    if new_lines:
      lines.extend(new_lines)
      lines.append("")

  return "\n".join(lines)


def ConvertMisc():
  """Convert some extra computed-values to Haskell.

  """
  lines = [""]
  lines.extend(ConvertVariable("opcodes", "OP_IDS",
                               opcodes.OP_MAPPING.keys(), {}))
  return "\n".join(lines)


def main():
  print Convert(constants, "")
  print Convert(luxi, "luxi")
  print Convert(qlang, "qlang")
  print Convert(_autoconf, "autoconf")
  print Convert(errors, "errors")
  print Convert(jstore, "jstore")
  print ConvertMisc()


if __name__ == "__main__":
  main()
