#!/usr/bin/python
#

# Copyright (C) 2011 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Script to generate RPC code.

"""

# pylint: disable=C0103
# [C0103] Invalid name

import sys
import re
import itertools
import textwrap
from cStringIO import StringIO

from ganeti import utils
from ganeti import compat
from ganeti import build


_SINGLE = "single-node"
_MULTI = "multi-node"

#: Expected length of a rpc definition
_RPC_DEF_LEN = 8


def _WritePreamble(sw):
  """Writes a preamble for the RPC wrapper output.

  """
  sw.Write("# This code is automatically generated at build time.")
  sw.Write("# Do not modify manually.")
  sw.Write("")
  sw.Write("\"\"\"Automatically generated RPC client wrappers.")
  sw.Write("")
  sw.Write("\"\"\"")
  sw.Write("")
  sw.Write("from ganeti import rpc_defs")
  sw.Write("")


def _WrapCode(line):
  """Wraps Python code.

  """
  return textwrap.wrap(line, width=70, expand_tabs=False,
                       fix_sentence_endings=False, break_long_words=False,
                       replace_whitespace=True,
                       subsequent_indent=utils.ShellWriter.INDENT_STR)


def _WriteDocstring(sw, name, timeout, kind, args, desc):
  """Writes a docstring for an RPC wrapper.

  """
  sw.Write("\"\"\"Wrapper for RPC call '%s'", name)
  sw.Write("")
  if desc:
    sw.Write(desc)
    sw.Write("")

  note = ["This is a %s call" % kind]
  if timeout and not callable(timeout):
    note.append(" with a timeout of %s" % utils.FormatSeconds(timeout))
  sw.Write("@note: %s", "".join(note))

  if kind == _SINGLE:
    sw.Write("@type node: string")
    sw.Write("@param node: Node name")
  else:
    sw.Write("@type node_list: list of string")
    sw.Write("@param node_list: List of node names")

  if args:
    for (argname, _, argtext) in args:
      if argtext:
        docline = "@param %s: %s" % (argname, argtext)
        for line in _WrapCode(docline):
          sw.Write(line)
  sw.Write("")
  sw.Write("\"\"\"")


def _WriteBaseClass(sw, clsname, calls):
  """Write RPC wrapper class.

  """
  sw.Write("")
  sw.Write("class %s(object):", clsname)
  sw.IncIndent()
  try:
    sw.Write("# E1101: Non-existent members")
    sw.Write("# R0904: Too many public methods")
    sw.Write("# pylint: disable=E1101,R0904")

    if not calls:
      sw.Write("pass")
      return

    sw.Write("_CALLS = rpc_defs.CALLS[%r]", clsname)
    sw.Write("")

    for v in calls:
      if len(v) != _RPC_DEF_LEN:
        raise ValueError("Procedure %s has only %d elements, expected %d" %
                         (v[0], len(v), _RPC_DEF_LEN))

    for (name, kind, _, timeout, args, _, _, desc) in sorted(calls):
      funcargs = ["self"]

      if kind == _SINGLE:
        funcargs.append("node")
      elif kind == _MULTI:
        funcargs.append("node_list")
      else:
        raise Exception("Unknown kind '%s'" % kind)

      funcargs.extend(map(compat.fst, args))

      funcargs.append("_def=_CALLS[%r]" % name)

      funcdef = "def call_%s(%s):" % (name, utils.CommaJoin(funcargs))
      for line in _WrapCode(funcdef):
        sw.Write(line)

      sw.IncIndent()
      try:
        _WriteDocstring(sw, name, timeout, kind, args, desc)

        buf = StringIO()
        buf.write("return ")

        # In case line gets too long and is wrapped in a bad spot
        buf.write("(")

        buf.write("self._Call(_def, ")
        if kind == _SINGLE:
          buf.write("[node]")
        else:
          buf.write("node_list")

        buf.write(", [%s])" %
                  # Function arguments
                  utils.CommaJoin(map(compat.fst, args)))

        if kind == _SINGLE:
          buf.write("[node]")
        buf.write(")")

        for line in _WrapCode(buf.getvalue()):
          sw.Write(line)
      finally:
        sw.DecIndent()
      sw.Write("")
  finally:
    sw.DecIndent()


def main():
  """Main function.

  """
  buf = StringIO()
  sw = utils.ShellWriter(buf)

  _WritePreamble(sw)

  for filename in sys.argv[1:]:
    sw.Write("# Definitions from '%s'", filename)

    module = build.LoadModule(filename)

    # Call types are re-defined in definitions file to avoid imports. Verify
    # here to ensure they're equal to local constants.
    assert module.SINGLE == _SINGLE
    assert module.MULTI == _MULTI

    dups = utils.GetRepeatedKeys(*module.CALLS.values())
    if dups:
      raise Exception("Found duplicate RPC definitions for '%s'" %
                      utils.CommaJoin(sorted(dups)))

    for (clsname, calls) in sorted(module.CALLS.items()):
      _WriteBaseClass(sw, clsname, calls.values())

  print buf.getvalue()


if __name__ == "__main__":
  main()
