# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Base class for generating wrapper functions for PPAPI methods.
"""

from datetime import datetime
import os
import sys

from idl_c_proto import CGen
from idl_generator import Generator
from idl_log import ErrOut, InfoOut, WarnOut
from idl_option import  GetOption
from idl_outfile import IDLOutFile


class PPKind(object):
  @staticmethod
  def ChoosePPFunc(iface, ppb_func, ppp_func):
    name = iface.node.GetName()
    if name.startswith("PPP"):
      return ppp_func
    elif name.startswith("PPB"):
      return ppb_func
    else:
      raise Exception('Unknown PPKind for ' + name)


class Interface(object):
  """Tracks information about a particular interface version.

  - struct_name: the struct type used by the ppapi headers to hold the
  method pointers (the vtable).
  - needs_wrapping: True if a method in the interface needs wrapping.
  - header_file: the name of the header file that defined this interface.
  """
  def __init__(self, interface_node, release, version,
               struct_name, needs_wrapping, header_file):
    self.node = interface_node
    self.release = release
    self.version = version
    self.struct_name = struct_name
    # We may want finer grained filtering (method level), but it is not
    # yet clear how to actually do that.
    self.needs_wrapping = needs_wrapping
    self.header_file = header_file


class WrapperGen(Generator):
  """WrapperGen - An abstract class that generates wrappers for PPAPI methods.

  This generates a wrapper PPB and PPP GetInterface, which directs users
  to wrapper PPAPI methods. Wrapper PPAPI methods may perform arbitrary
  work before invoking the real PPAPI method (supplied by the original
  GetInterface functions).

  Subclasses must implement GenerateWrapperForPPBMethod (and PPP).
  """

  def __init__(self, wrapper_prefix, s1, s2, s3):
    Generator.__init__(self, s1, s2, s3)
    self.wrapper_prefix = wrapper_prefix
    self._skip_opt = False
    self.output_file = None
    self.cgen = CGen()

  def SetOutputFile(self, fname):
    self.output_file = fname


  def GenerateRelease(self, ast, release, options):
    return self.GenerateRange(ast, [release], options)


  @staticmethod
  def GetHeaderName(name):
    """Get the corresponding ppapi .h file from each IDL filename.
    """
    name = os.path.splitext(name)[0] + '.h'
    name = name.replace(os.sep, '/')
    return 'ppapi/c/' + name


  def WriteCopyright(self, out):
    now = datetime.now()
    c = """/* Copyright (c) %s The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* NOTE: this is auto-generated from IDL */
""" % now.year
    out.Write(c)

  def GetWrapperMetadataName(self):
    return '__%sWrapperInfo' % self.wrapper_prefix


  def GenerateHelperFunctions(self, out):
    """Generate helper functions to avoid dependencies on libc.
    """
    out.Write("""/* Use local strcmp to avoid dependency on libc. */
static int mystrcmp(const char* s1, const char *s2) {
  while (1) {
    if (*s1 == 0) break;
    if (*s2 == 0) break;
    if (*s1 != *s2) break;
    ++s1;
    ++s2;
  }
  return (int)(*s1) - (int)(*s2);
}\n
""")


  def GenerateFixedFunctions(self, out):
    """Write out the set of constant functions (those that do not depend on
    the current Pepper IDL).
    """
    out.Write("""

static PPB_GetInterface __real_PPBGetInterface;
static PPP_GetInterface_Type __real_PPPGetInterface;

void __set_real_%(wrapper_prefix)s_PPBGetInterface(PPB_GetInterface real) {
  __real_PPBGetInterface = real;
}

void __set_real_%(wrapper_prefix)s_PPPGetInterface(PPP_GetInterface_Type real) {
  __real_PPPGetInterface = real;
}

/* Map interface string -> wrapper metadata */
static struct %(wrapper_struct)s *%(wrapper_prefix)sPPBShimIface(
    const char *name) {
  struct %(wrapper_struct)s **next = s_ppb_wrappers;
  while (*next != NULL) {
    if (mystrcmp(name, (*next)->iface_macro) == 0) return *next;
    ++next;
  }
  return NULL;
}

/* Map interface string -> wrapper metadata */
static struct %(wrapper_struct)s *%(wrapper_prefix)sPPPShimIface(
    const char *name) {
  struct %(wrapper_struct)s **next = s_ppp_wrappers;
  while (*next != NULL) {
    if (mystrcmp(name, (*next)->iface_macro) == 0) return *next;
    ++next;
  }
  return NULL;
}

const void *__%(wrapper_prefix)s_PPBGetInterface(const char *name) {
  struct %(wrapper_struct)s *wrapper = %(wrapper_prefix)sPPBShimIface(name);
  if (wrapper == NULL) {
    /* We did not generate a wrapper for this, so return the real interface. */
    return (*__real_PPBGetInterface)(name);
  }

  /* Initialize the real_iface if it hasn't been. The wrapper depends on it. */
  if (wrapper->real_iface == NULL) {
    const void *iface = (*__real_PPBGetInterface)(name);
    if (NULL == iface) return NULL;
    wrapper->real_iface = iface;
  }

  return wrapper->wrapped_iface;
}

const void *__%(wrapper_prefix)s_PPPGetInterface(const char *name) {
  struct %(wrapper_struct)s *wrapper = %(wrapper_prefix)sPPPShimIface(name);
  if (wrapper == NULL) {
    /* We did not generate a wrapper for this, so return the real interface. */
    return (*__real_PPPGetInterface)(name);
  }

  /* Initialize the real_iface if it hasn't been. The wrapper depends on it. */
  if (wrapper->real_iface == NULL) {
    const void *iface = (*__real_PPPGetInterface)(name);
    if (NULL == iface) return NULL;
    wrapper->real_iface = iface;
  }

  return wrapper->wrapped_iface;
}
""" % { 'wrapper_struct' : self.GetWrapperMetadataName(),
        'wrapper_prefix' : self.wrapper_prefix,
        } )


  ############################################################

  def OwnHeaderFile(self):
    """Return the header file that specifies the API of this wrapper.
    We do not generate the header files.  """
    raise Exception('Child class must implement this')


  ############################################################

  def DetermineInterfaces(self, ast, releases):
    """Get a list of interfaces along with whatever metadata we need.
    """
    iface_releases = []
    for filenode in ast.GetListOf('File'):
      # If this file has errors, skip it
      if filenode in self.skip_list:
        if GetOption('verbose'):
          InfoOut.Log('WrapperGen: Skipping %s due to errors\n' %
                      filenode.GetName())
        continue

      file_name = self.GetHeaderName(filenode.GetName())
      ifaces = filenode.GetListOf('Interface')
      for iface in ifaces:
        releases_for_iface = iface.GetUniqueReleases(releases)
        for release in releases_for_iface:
          version = iface.GetVersion(release)
          struct_name = self.cgen.GetStructName(iface, release,
                                                include_version=True)
          needs_wrap = self.InterfaceVersionNeedsWrapping(iface, version)
          if not needs_wrap:
            if GetOption('verbose'):
              InfoOut.Log('Interface %s ver %s does not need wrapping' %
                          (struct_name, version))
          iface_releases.append(
              Interface(iface, release, version,
                        struct_name, needs_wrap, file_name))
    return iface_releases


  def GenerateIncludes(self, iface_releases, out):
    """Generate the list of #include that define the original interfaces.
    """
    self.WriteCopyright(out)
    # First include own header.
    out.Write('#include "%s"\n\n' % self.OwnHeaderFile())

    # Get typedefs for PPB_GetInterface.
    out.Write('#include "%s"\n' % self.GetHeaderName('ppb.h'))

    # Only include headers where *some* interface needs wrapping.
    header_files = set()
    for iface in iface_releases:
      if iface.needs_wrapping:
        header_files.add(iface.header_file)
    for header in sorted(header_files):
      out.Write('#include "%s"\n' % header)
    out.Write('\n')


  def WrapperMethodPrefix(self, iface, release):
    return '%s_%s_%s_' % (self.wrapper_prefix, release, iface.GetName())


  def GenerateWrapperForPPBMethod(self, iface, member):
    result = []
    func_prefix = self.WrapperMethodPrefix(iface.node, iface.release)
    sig = self.cgen.GetSignature(member, iface.release, 'store',
                                 func_prefix, False)
    result.append('static %s {\n' % sig)
    result.append(' while(1) { /* Not implemented */ } \n')
    result.append('}\n')
    return result


  def GenerateWrapperForPPPMethod(self, iface, member):
    result = []
    func_prefix = self.WrapperMethodPrefix(iface.node, iface.release)
    sig = self.cgen.GetSignature(member, iface.release, 'store',
                                 func_prefix, False)
    result.append('static %s {\n' % sig)
    result.append(' while(1) { /* Not implemented */ } \n')
    result.append('}\n')
    return result


  def GenerateWrapperForMethods(self, iface_releases, comments=True):
    """Return a string representing the code for each wrapper method
    (using a string rather than writing to the file directly for testing.)
    """
    result = []
    for iface in iface_releases:
      if not iface.needs_wrapping:
        if comments:
          result.append('/* Not generating wrapper methods for %s */\n\n' %
                        iface.struct_name)
        continue
      if comments:
        result.append('/* Begin wrapper methods for %s */\n\n' %
                      iface.struct_name)
      generator =  PPKind.ChoosePPFunc(iface,
                                       self.GenerateWrapperForPPBMethod,
                                       self.GenerateWrapperForPPPMethod)
      for member in iface.node.GetListOf('Member'):
        # Skip the method if it's not actually in the release.
        if not member.InReleases([iface.release]):
          continue
        result.extend(generator(iface, member))
      if comments:
        result.append('/* End wrapper methods for %s */\n\n' %
                      iface.struct_name)
    return ''.join(result)


  def GenerateWrapperInterfaces(self, iface_releases, out):
    for iface in iface_releases:
      if not iface.needs_wrapping:
        out.Write('/* Not generating wrapper interface for %s */\n\n' %
                  iface.struct_name)
        continue

      out.Write('static const struct %s %s_Wrappers_%s = {\n' % (
          iface.struct_name, self.wrapper_prefix, iface.struct_name))
      methods = []
      for member in iface.node.GetListOf('Member'):
        # Skip the method if it's not actually in the release.
        if not member.InReleases([iface.release]):
          continue
        prefix = self.WrapperMethodPrefix(iface.node, iface.release)
        # Casts are necessary for the PPB_* wrappers because we must
        # cast away "__attribute__((pnaclcall))".  The PPP_* wrappers
        # must match the default calling conventions and so don't have
        # the attribute, so omitting casts for them provides a little
        # extra type checking.
        if iface.node.GetName().startswith('PPB_'):
          cast = '(%s)' % self.cgen.GetSignature(
              member, iface.release, 'return',
              prefix='',
              func_as_ptr=True,
              include_name=False)
        else:
          cast = ''
        methods.append('  .%s = %s&%s%s' % (member.GetName(),
                                            cast,
                                            prefix,
                                            member.GetName()))
      out.Write('  ' + ',\n  '.join(methods) + '\n')
      out.Write('};\n\n')


  def GetWrapperInfoName(self, iface):
    return '%s_WrapperInfo_%s' % (self.wrapper_prefix, iface.struct_name)


  def GenerateWrapperInfoAndCollection(self, iface_releases, out):
    for iface in iface_releases:
      iface_macro = self.cgen.GetInterfaceMacro(iface.node, iface.version)
      if iface.needs_wrapping:
        wrap_iface = '(const void *) &%s_Wrappers_%s' % (self.wrapper_prefix,
                                                         iface.struct_name)
        out.Write("""static struct %s %s = {
  .iface_macro = %s,
  .wrapped_iface = %s,
  .real_iface = NULL
};\n\n""" % (self.GetWrapperMetadataName(),
             self.GetWrapperInfoName(iface),
             iface_macro,
             wrap_iface))

    # Now generate NULL terminated arrays of the above wrapper infos.
    ppb_wrapper_infos = []
    ppp_wrapper_infos = []
    for iface in iface_releases:
      if iface.needs_wrapping:
        appender = PPKind.ChoosePPFunc(iface,
                                       ppb_wrapper_infos.append,
                                       ppp_wrapper_infos.append)
        appender('  &%s' % self.GetWrapperInfoName(iface))
    ppb_wrapper_infos.append('  NULL')
    ppp_wrapper_infos.append('  NULL')
    out.Write(
        'static struct %s *s_ppb_wrappers[] = {\n%s\n};\n\n' %
        (self.GetWrapperMetadataName(), ',\n'.join(ppb_wrapper_infos)))
    out.Write(
        'static struct %s *s_ppp_wrappers[] = {\n%s\n};\n\n' %
        (self.GetWrapperMetadataName(), ',\n'.join(ppp_wrapper_infos)))


  def DeclareWrapperInfos(self, iface_releases, out):
    """The wrapper methods usually need access to the real_iface, so we must
    declare these wrapper infos ahead of time (there is a circular dependency).
    """
    out.Write('/* BEGIN Declarations for all Wrapper Infos */\n\n')
    for iface in iface_releases:
      if iface.needs_wrapping:
        out.Write('static struct %s %s;\n' %
                  (self.GetWrapperMetadataName(),
                   self.GetWrapperInfoName(iface)))
    out.Write('/* END Declarations for all Wrapper Infos. */\n\n')


  def GenerateRange(self, ast, releases, options):
    """Generate shim code for a range of releases.
    """

    # Remember to set the output filename before running this.
    out_filename = self.output_file
    if out_filename is None:
      ErrOut.Log('Did not set filename for writing out wrapper\n')
      return 1

    InfoOut.Log("Generating %s for %s" % (out_filename, self.wrapper_prefix))

    out = IDLOutFile(out_filename)

    # Get a list of all the interfaces along with metadata.
    iface_releases = self.DetermineInterfaces(ast, releases)

    # Generate the includes.
    self.GenerateIncludes(iface_releases, out)

    # Write out static helper functions (mystrcmp).
    self.GenerateHelperFunctions(out)

    # Declare list of WrapperInfo before actual wrapper methods, since
    # they reference each other.
    self.DeclareWrapperInfos(iface_releases, out)

    # Generate wrapper functions for each wrapped method in the interfaces.
    result = self.GenerateWrapperForMethods(iface_releases)
    out.Write(result)

    # Collect all the wrapper functions into interface structs.
    self.GenerateWrapperInterfaces(iface_releases, out)

    # Generate a table of the wrapped interface structs that can be looked up.
    self.GenerateWrapperInfoAndCollection(iface_releases, out)

    # Write out the IDL-invariant functions.
    self.GenerateFixedFunctions(out)

    out.Close()
    return 0
