#!/usr/bin/env python
# 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.

"""
Creates a library loader (a header and implementation file),
which is a wrapper for dlopen or direct linking with given library.

The loader makes it possible to have the same client code for both cases,
and also makes it easier to write code using dlopen (and also provides
a standard way to do so, and limits the ugliness just to generated files).

For more info refer to http://crbug.com/162733 .
"""


import optparse
import os.path
import re
import sys


HEADER_TEMPLATE = """// This is generated file. Do not modify directly.
// Path to the code generator: %(generator_path)s .

#ifndef %(unique_prefix)s
#define %(unique_prefix)s

%(wrapped_header_include)s

#include <string>

class %(class_name)s {
 public:
  %(class_name)s();
  ~%(class_name)s();

  bool Load(const std::string& library_name)
      __attribute__((warn_unused_result));

  bool loaded() const { return loaded_; }

%(member_decls)s

 private:
  void CleanUp(bool unload);

#if defined(%(unique_prefix)s_DLOPEN)
  void* library_;
#endif

  bool loaded_;

  // Disallow copy constructor and assignment operator.
  %(class_name)s(const %(class_name)s&);
  void operator=(const %(class_name)s&);
};

#endif  // %(unique_prefix)s
"""


HEADER_MEMBER_TEMPLATE = """  typeof(&::%(function_name)s) %(function_name)s;
"""


IMPL_TEMPLATE = """// This is generated file. Do not modify directly.
// Path to the code generator: %(generator_path)s .

#include "%(generated_header_name)s"

#include <dlfcn.h>

// Put these sanity checks here so that they fire at most once
// (to avoid cluttering the build output).
#if !defined(%(unique_prefix)s_DLOPEN) && !defined(%(unique_prefix)s_DT_NEEDED)
#error neither %(unique_prefix)s_DLOPEN nor %(unique_prefix)s_DT_NEEDED defined
#endif
#if defined(%(unique_prefix)s_DLOPEN) && defined(%(unique_prefix)s_DT_NEEDED)
#error both %(unique_prefix)s_DLOPEN and %(unique_prefix)s_DT_NEEDED defined
#endif

%(class_name)s::%(class_name)s() : loaded_(false) {
}

%(class_name)s::~%(class_name)s() {
  CleanUp(loaded_);
}

bool %(class_name)s::Load(const std::string& library_name) {
  if (loaded_)
    return false;

#if defined(%(unique_prefix)s_DLOPEN)
  library_ = dlopen(library_name.c_str(), RTLD_LAZY);
  if (!library_)
    return false;
#endif

%(member_init)s

  loaded_ = true;
  return true;
}

void %(class_name)s::CleanUp(bool unload) {
#if defined(%(unique_prefix)s_DLOPEN)
  if (unload) {
    dlclose(library_);
    library_ = NULL;
  }
#endif
  loaded_ = false;
%(member_cleanup)s
}
"""

IMPL_MEMBER_INIT_TEMPLATE = """
#if defined(%(unique_prefix)s_DLOPEN)
  %(function_name)s =
      reinterpret_cast<typeof(this->%(function_name)s)>(
          dlsym(library_, "%(function_name)s"));
#endif
#if defined(%(unique_prefix)s_DT_NEEDED)
  %(function_name)s = &::%(function_name)s;
#endif
  if (!%(function_name)s) {
    CleanUp(true);
    return false;
  }
"""

IMPL_MEMBER_CLEANUP_TEMPLATE = """  %(function_name)s = NULL;
"""

def main():
  parser = optparse.OptionParser()
  parser.add_option('--name')
  parser.add_option('--output-cc')
  parser.add_option('--output-h')
  parser.add_option('--header')

  parser.add_option('--bundled-header')
  parser.add_option('--use-extern-c', action='store_true', default=False)
  parser.add_option('--link-directly', type=int, default=0)

  options, args = parser.parse_args()

  if not options.name:
    parser.error('Missing --name parameter')
  if not options.output_cc:
    parser.error('Missing --output-cc parameter')
  if not options.output_h:
    parser.error('Missing --output-h parameter')
  if not options.header:
    parser.error('Missing --header paramater')
  if not args:
    parser.error('No function names specified')

  # Make sure we are always dealing with paths relative to source tree root
  # to avoid issues caused by different relative path roots.
  source_tree_root = os.path.abspath(
    os.path.join(os.path.dirname(__file__), '..', '..'))
  options.output_cc = os.path.relpath(options.output_cc, source_tree_root)
  options.output_h = os.path.relpath(options.output_h, source_tree_root)

  # Create a unique prefix, e.g. for header guards.
  # Stick a known string at the beginning to ensure this doesn't begin
  # with an underscore, which is reserved for the C++ implementation.
  unique_prefix = ('LIBRARY_LOADER_' +
                   re.sub(r'[\W]', '_', options.output_h).upper())

  member_decls = []
  member_init = []
  member_cleanup = []
  for fn in args:
    member_decls.append(HEADER_MEMBER_TEMPLATE % {
      'function_name': fn,
      'unique_prefix': unique_prefix
    })
    member_init.append(IMPL_MEMBER_INIT_TEMPLATE % {
      'function_name': fn,
      'unique_prefix': unique_prefix
    })
    member_cleanup.append(IMPL_MEMBER_CLEANUP_TEMPLATE % {
      'function_name': fn,
      'unique_prefix': unique_prefix
    })

  header = options.header
  if options.link_directly == 0 and options.bundled_header:
    header = options.bundled_header
  wrapped_header_include = '#include %s\n' % header

  # Some libraries (e.g. libpci) have headers that cannot be included
  # without extern "C", otherwise they cause the link to fail.
  # TODO(phajdan.jr): This is a workaround for broken headers. Remove it.
  if options.use_extern_c:
    wrapped_header_include = 'extern "C" {\n%s\n}\n' % wrapped_header_include

  # It seems cleaner just to have a single #define here and #ifdefs in bunch
  # of places, rather than having a different set of templates, duplicating
  # or complicating more code.
  if options.link_directly == 0:
    wrapped_header_include += '#define %s_DLOPEN\n' % unique_prefix
  elif options.link_directly == 1:
    wrapped_header_include += '#define %s_DT_NEEDED\n' % unique_prefix
  else:
    parser.error('Invalid value for --link-directly. Should be 0 or 1.')

  # Make it easier for people to find the code generator just in case.
  # Doing it this way is more maintainable, because it's going to work
  # even if file gets moved without updating the contents.
  generator_path = os.path.relpath(__file__, source_tree_root)

  header_contents = HEADER_TEMPLATE % {
    'generator_path': generator_path,
    'unique_prefix': unique_prefix,
    'wrapped_header_include': wrapped_header_include,
    'class_name': options.name,
    'member_decls': ''.join(member_decls),
  }

  impl_contents = IMPL_TEMPLATE % {
    'generator_path': generator_path,
    'unique_prefix': unique_prefix,
    'generated_header_name': options.output_h,
    'class_name': options.name,
    'member_init': ''.join(member_init),
    'member_cleanup': ''.join(member_cleanup),
  }

  header_file = open(os.path.join(source_tree_root, options.output_h), 'w')
  try:
    header_file.write(header_contents)
  finally:
    header_file.close()

  impl_file = open(os.path.join(source_tree_root, options.output_cc), 'w')
  try:
    impl_file.write(impl_contents)
  finally:
    impl_file.close()

  return 0

if __name__ == '__main__':
  sys.exit(main())
