#! /usr/bin/env python3

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

import os.path
import sys
import datetime
import collections


class GnVariables(collections.OrderedDict):

  def __setitem__(self, key, value):
    if isinstance(value, list):
      value = SetGnListValue(value)
    super().__setitem__(key, value)
    super().move_to_end(key)


class GnListValue(object):

  def __init__(self, items):
    assert (isinstance(items, list))
    self._items = items

  def __getitem__(self, idx):
    return self._items[idx]

  def __len__(self):
    return len(self._items)

  def __iter__(self):
    yield from self._items


class RemoveGnListValue(GnListValue):
  pass


class SetGnListValue(GnListValue):
  pass


def IsSubdir(parent, child):
  if parent == child:
    return False
  return (os.path.commonpath([parent, child]) == parent)


class BazelGlobals(object):
  IGNORABLES = frozenset([
      'load',
      'package',
      'licenses',
      'exports_files',
      'select',
  ])

  def __init__(self, build_graph, dirpath):
    self._build_graph = build_graph
    self._dirpath = dirpath
    self._set_objects = {}

  def __getitem__(self, key):
    if key in self._set_objects:
      return self._set_objects[key]

    if key == '__builtins__':
      raise KeyError(key)

    if key in self.IGNORABLES:
      return lambda *args, **kwargs: None

    return self._build_graph.GetTargetAdder(self._dirpath, key)

  def __setitem__(self, key, value):
    self._set_objects[key] = value

  def __contains__(self, key):
    if key == '__builtins__':
      raise KeyError(key)

    return True

  def __len__(self):
    return 1


class BuildGraph(object):

  def __init__(self, root_path, ignored_targets):
    self._targets = {}
    if not os.path.isabs(root_path):
      raise Exception('{} is not an absolute path.'.format(root_path))
    self._root_path = root_path
    self._ignored_targets = ignored_targets

    # These are specs that will be remapped.
    self._spec_map_old_to_new = {}

  def AddTarget(self, target_cls, dirpath, name, deps=None, **kwargs):
    if deps:
      deps = [MakeTargetRef(dep, dirpath) for dep in deps]
      deps = [dep for dep in deps if dep.spec() not in self._ignored_targets]
      for i in range(len(deps)):
        if deps[i].spec() not in self._spec_map_old_to_new:
          continue
        deps[i] = MakeTargetRef(self._spec_map_old_to_new[deps[i].spec()],
                                dirpath)

    target = target_cls(
        dirpath=dirpath,
        name=name,
        sort_id=len(self._targets),
        deps=deps,
        **kwargs)
    assert (isinstance(target, Target))
    self._targets[target.spec()] = target

  def GetTargetAdder(self, absdirpath, target_type):
    if not IsSubdir(self._root_path, absdirpath):
      Exception(
          'GetTargetAdder expected a path under {} which {} is not.'.format(
              self._root_path, absdirpath))
    dirpath = os.path.relpath(absdirpath, self._root_path)
    if target_type == 'proto_library':
      return self.GetProtoLibraryAdder(dirpath)
    elif target_type == 'cc_library':
      return self.GetCcLibraryAdder(dirpath)
    elif target_type == 'cc_proto_library':
      return self.GetCcProtoLibraryAdder(dirpath)
    return self.GetUnknownTargetAdder(dirpath, target_type)

  def GetUnknownTargetAdder(self, dirpath, target_type):

    def Add(*args, **kwargs):
      if 'name' not in kwargs or args:
        raise Exception(
            '"{}" is not a target type. Please add to IGNORABLES.'.format(
                target_type))
      name = kwargs['name']
      deps = kwargs.get('deps', [])
      self.AddTarget(
          UnknownTarget, dirpath, name, deps=deps, target_type=target_type)

    return Add

  def GetCcProtoLibraryAdder(self, dirpath):

    def Add(name, deps=None, **kwargs):
      self.AddTarget(CcProtoLibTarget, dirpath, name, deps=deps)

    return Add

  def GetProtoLibraryAdder(self, dirpath):

    def Add(name, srcs, deps=None, **kwargs):
      self.AddTarget(ProtoLibTarget, dirpath, name, srcs=srcs, deps=deps)

    return Add

  def GetCcLibraryAdder(self, dirpath):

    def Add(name, srcs=None, hdrs=None, deps=None, **kwargs):
      self.AddTarget(
          CcLibTarget, dirpath, name, hdrs=hdrs, srcs=srcs, deps=deps)

    return Add

  def AddToGraph(self, dirpath):
    filepath = os.path.join(dirpath, 'BUILD.bazel')
    fp = open(filepath, 'r')
    content = fp.read()
    gs = BazelGlobals(self, dirpath)
    exec(content, {}, gs)

  def GetTarget(self, target_spec):
    target_spec = self._spec_map_old_to_new.get(target_spec, target_spec)
    if target_spec in self._ignored_targets:
      raise Exception('{} is being ignored'.format(target_spec))
    ref = MakeTargetRef(target_spec, '')
    if not ref.InTree():
      raise Exception('{} is not in the tree.'.format(target_spec))
    if target_spec not in self._targets:
      dirpath, _ = ParseTargetSpec(target_spec)
      absdirpath = os.path.join(self._root_path, dirpath)
      self.AddToGraph(absdirpath)
      if target_spec not in self._targets:
        print(self._targets.keys())
        raise Exception('{} could not be found in {}'.format(
            target_spec, absdirpath))

    return self._targets[target_spec]


##############################################################
# The Targets themselves.
##############################################################
class Target(object):

  def __init__(self, dirpath, name, sort_id, deps):
    assert (isinstance(sort_id, int))
    self._sort_id = sort_id
    assert (isinstance(name, str))
    self._name = name
    assert (isinstance(dirpath, str))
    self._dirpath = dirpath
    self._deps = deps or []
    assert (all(isinstance(dep, TargetRef) for dep in self._deps))

  def __repr__(self):
    raise NotImplementedError

  def name(self):
    return self._name

  def spec(self):
    # When target is added to graph, the relative dirpath is computed by
    # os.path.relpath(absdirpath, root_path). The function returns '.' as
    # dirpath for the targets lives in root dir.
    #
    # Skip dirpath '.' to avoid returning spec like '//.:target'.
    dirpath = self._dirpath if self._dirpath != '.' else ''
    return '//{}:{}'.format(dirpath, self._name)

  def deps(self):
    return self._deps

  def dirpath(self):
    return self._dirpath

  def sort_id(self):
    return self._sort_id

  def target_type(self):
    raise NotImplementedError

  def IsUnknown(self):
    return False

  def IsProto(self):
    return False

  def RemapDep(self, old, new):
    for i in range(len(self._deps)):
      if self._deps[i].spec() == old:
        self._deps[i] = MakeTargetRef(new, self._dirpath)


class UnknownTarget(Target):

  def __init__(self, dirpath, name, sort_id, target_type, deps):
    super().__init__(dirpath, name, sort_id, deps=deps)
    assert (isinstance(target_type, str))
    self._target_type = target_type

  def __repr__(self):
    return 'UnknownTarget<{}: {}>'.format(self._target_type, self.spec())

  def IsUnknown(self):
    return True


class LibTarget(Target):

  def __init__(self, dirpath, name, sort_id, deps, srcs=None):
    super().__init__(dirpath, name, sort_id, deps)
    self.srcs = srcs or []

  def __repr__(self):
    return 'LibTarget<{}>'.format(self.spec())


class ProtoLibTarget(LibTarget):

  def IsProto(self):
    return True

  def __repr__(self):
    return 'ProtoLibTarget<{}>'.format(self.spec())

  def target_type(self):
    return 'Proto Library'


class CcProtoLibTarget(Target):

  def IsProto(self):
    return True

  def __repr__(self):
    return 'CcProtoLibTarget<{}>'.format(self.spec())

  def target_type(self):
    return 'CC Proto Library'


class CcLibTarget(LibTarget):

  def __init__(self, dirpath, name, sort_id, deps, srcs=None, hdrs=None):
    super().__init__(dirpath, name, sort_id, srcs=srcs, deps=deps)
    self.hdrs = hdrs or []

  def __repr__(self):
    return 'CcLibTarget<{}>'.format(self.spec())

  def target_type(self):
    return 'CC Library'


##############################################################
# Target references. (Used mostly for dependencies)
##############################################################
def ParseTargetSpec(dep):
  parts = dep.split(':')
  dirpath = parts[0][2:]
  if len(parts) == 1:
    name = os.path.basename(dep)
  elif len(parts) == 2:
    name = parts[1]
  else:
    raise Exception('I do not know how to deal with this dep: "{}"'.format(dep))

  return dirpath, name


def MakeTargetRef(dep, dirpath):
  if dep[0] == ':':
    return InTreeTargetRef(dirpath, dep[1:])
  if dep[:2] == '//':
    dirpath, name = ParseTargetSpec(dep)
    return InTreeTargetRef(dirpath, name)

  tink_base_prefix = '@tink_base'
  if dep.startswith(tink_base_prefix):
    dep = dep[len(tink_base_prefix):]
    dirpath, name = ParseTargetSpec(dep)
    return TinkBaseTargetRef(dirpath, name)

  absl_prefix = '@com_google_absl'
  if dep.startswith(absl_prefix):
    dep = dep[len(absl_prefix):]
    dirpath, name = ParseTargetSpec(dep)
    return AbslTargetRef(dirpath, name)

  if dep == '@com_google_protobuf//:protobuf_lite':
    return ProtobufLiteTargetRef()

  if dep == '@com_google_protobuf//:protobuf':
    return ProtobufLiteTargetRef()

  if dep == '@rapidjson':
    return RapidJsonTargetRef()

  googletest_prefix = '@com_google_googletest'
  if dep.startswith(googletest_prefix):
    dep = dep[len(googletest_prefix):]
    dirpath, name = ParseTargetSpec(dep)
    return GoogleTestTargetRef(dirpath, name)

  boringssl_prefix = '@boringssl'
  if dep.startswith(boringssl_prefix):
    dep = dep[len(boringssl_prefix):]
    dirpath, name = ParseTargetSpec(dep)
    return BoringSslTargetRef(dirpath, name)

  return UnknownTargetRef(dirpath, dep)


class TargetRef(object):

  def InTree(self):
    return False

  def IsUnknown(self):
    return False


class UnknownTargetRef(TargetRef):
  def __init__(self, dirpath, dep):
    self._dirpath = dirpath
    self._dep = dep

  def IsUnknown(self):
    return True

  def spec(self):
    return '<{} in {}'.format(self._dep, self._dirpath)


class PathTargetRef(TargetRef):

  def __init__(self, dirpath, name):
    self._dirpath = dirpath
    self._name = name

  def name(self):
    return self._name

  def spec(self):
    # When target is added to graph, the relative dirpath is computed by
    # os.path.relpath(absdirpath, root_path). The function returns '.' as
    # dirpath for the targets lives in root dir. The relative dirpath is
    # also used to make TargetRefs for the target's dependencies.
    #
    # Skip dirpath '.' to avoid returning spec like '//.:target'.
    dirpath = self._dirpath if self._dirpath != '.' else ''
    return '//{}:{}'.format(dirpath, self._name)

  def dirpath(self):
    return self._dirpath

  def __repr__(self):
    return '{}<{}>'.format(type(self).__name__, self.spec())


class TinkBaseTargetRef(PathTargetRef):

  def GetGnDep(self):
    spec = self.spec()
    prefix = '//'
    if not spec.startswith(prefix):
      raise Exception(
          'I do not know how to deal with Tink base dependency {}'.format(spec))
    return '//third_party/tink/' + spec[len(prefix):]


class InTreeTargetRef(PathTargetRef):

  def InTree(self):
    return True


class AbslTargetRef(PathTargetRef):

  def GetGnDep(self):
    spec = self.spec()
    prefix = '//'
    if not spec.startswith(prefix):
      raise Exception(
          'I do not know how to deal with Absl dependency {}'.format(spec))
    return '//third_party/abseil-cpp/' + spec[len(prefix):]


class GoogleTestTargetRef(PathTargetRef):
  pass


class ProtobufLiteTargetRef(TargetRef):

  def GetGnDep(self):
    return '//third_party/protobuf:protobuf_lite'

  def spec(self):
    return '@protobuf_lite'


class RapidJsonTargetRef(TargetRef):

  def spec(self):
    return '@rapidjson'


class BoringSslTargetRef(PathTargetRef):

  def GetGnDep(self):
    if self._dirpath:
      raise Exception(
          'BoringSSL dep {} has dirpath {}. I do not know how to deal with that.'
          .format(self.spec(), self._dirpath))
    return '//third_party/boringssl:' + self._name


##############################################################
# TargetFetcher grabs all the targets we need.
##############################################################
class TargetFetcher(object):

  def __init__(self, build_graph, initial_targets, error_on_unknown):
    # _to_fetch is a list of target specs.
    self._to_fetch = initial_targets
    self._targets = []
    self._fetched = set()
    self._build_graph = build_graph
    self._error_on_unknown = error_on_unknown

  def FetchAll(self):
    while self._to_fetch:
      self.FetchNext()
    return self._targets

  def FetchNext(self):
    spec = self._to_fetch.pop(0)
    if spec in self._fetched:
      return
    target = self._build_graph.GetTarget(spec)
    if target.IsUnknown() and self._error_on_unknown:
      raise Exception('Found unknown target: {}'.format(target))
    self._targets.append(target)

    # We add both the actual spec and the spec we tried to fetch just in
    # case there was a remapping.
    self._fetched.add(target.spec())
    self._fetched.add(spec)
    for dep in target.deps():
      if dep.IsUnknown():
        raise Exception('Found unknown dep: {} for {}'.format(dep.spec(), target.spec()))
      if not dep.InTree():
        continue
      if dep.spec() not in self._fetched:
        self._to_fetch.append(dep.spec())

##############################################################
# BuildFile holds the information necessary to create a build file.
##############################################################
class BuildFile(object):

  def __init__(self, dirpath, targets, subdirs):
    self.dirpath = dirpath
    # Directory mapping spec to target.
    self.targets = targets
    self.subdirs = sorted(subdirs)

  def HasProto(self):
    return any(t.IsProto() for t in self.targets.values())

  def HasCcLib(self):
    return any(isinstance(t, CcLibTarget) for t in self.targets.values())

  def __contains__(self, target_or_spec):
    spec = target_or_spec
    if hasattr(target_or_spec, 'spec'):
      spec = target_or_spec.spec()
    if not isinstance(spec, str):
      raise Exception(
          '{} should be a spec string or have a spec method.'.format(
              target_or_spec))

    return spec in self.targets


def CreateBuildFiles(targets):
  build_file_targets = {}
  for t in targets:
    if t.dirpath() not in build_file_targets:
      build_file_targets[t.dirpath()] = {}
    build_file_targets[t.dirpath()][t.spec()] = t

  dirpaths = [k for k in build_file_targets.keys()]
  build_files = []

  for dirpath, targets in build_file_targets.items():
    subdirs = []
    for d in dirpaths:
      # If d is an immediate subdirectory of dirpath, add it to subdirs
      if not IsSubdir(dirpath, d):
        continue
      rel = os.path.relpath(d, dirpath)
      if os.path.basename(rel) == rel:
        subdirs.append(rel)

    build_files.append(BuildFile(dirpath, targets, subdirs))

  return build_files


class BuildFileWriter(object):

  def __init__(self, rootdir, build_graph, max_line):
    self._rootdir = rootdir
    self._max_line = max_line
    self._build_graph = build_graph

  def GetTargetForInTreeDep(self, dep):
    assert (isinstance(dep, InTreeTargetRef))
    target = self._build_graph.GetTarget(dep.spec())
    return target

  def GetBuildFilePath(self, dirpath):
    raise NotImplementedError

  def WriteBuildFile(self, build_file):
    self._indent = 0
    self._filepath = self.GetBuildFilePath(build_file)
    self._fp = open(self._filepath, 'w+')
    self._build_file = build_file
    self._nl = False

    print('Writing to {},'.format(self._filepath))
    self.WriteHeader()
    # We generate a stable sort order to stabilize the .gn files.
    targets = sorted(
        build_file.targets.values(), key=lambda target: target.sort_id())

    for target in targets:
      self.WriteTarget(target)

    assert (self._indent == 0)

  def WriteHeader(self):
    year = datetime.datetime.today().year
    self.emitlines([
        '# Copyright {} The Fuchsia Authors. All rights reserved.'.format(year),
        '# Use of this source code is governed by a BSD-style license that can be',
        '# found in the LICENSE file.',
        '#',
        '# WARNING: This file is automatically generated by convert_for_cobalt.',
        '# Do not edit manually.'
    ])

  def WriteTarget(self, target):
    self.emitnl('# {} : {}'.format(target.target_type(), target.name()))

  def emit(self, s):
    if self._nl:
      self._fp.write('  ' * self._indent)
      self._nl = False
    if not isinstance(s, str):
      raise Exception('emit expected a string, not {}'.format(s))
    self._fp.write(s)

  def emitnl(self, s):
    self.emit(s)
    self.nl()

  def emitlines(self, lines):
    for line in lines:
      self.emitnl(line)

  def nl(self):
    self._fp.write('\n')
    self._nl = True

  def indent(self):
    self._indent += 1

  def deindent(self):
    self._indent -= 1


class GnWriter(BuildFileWriter):

  def __init__(self, rootdir, deps_prefix, build_graph, max_line):
    super().__init__(
        rootdir=rootdir, build_graph=build_graph, max_line=max_line)
    assert (deps_prefix.startswith('//'))
    assert (not deps_prefix.endswith('/'))
    self._deps_prefix = deps_prefix

  def GetBuildFilePath(self, build_file):
    return os.path.join(self._rootdir, build_file.dirpath, 'BUILD.gn')

  def WriteHeader(self):
    super().WriteHeader()
    if self._build_file.HasProto():
      self.nl()
      self.emitnl('import("//third_party/protobuf/proto_library.gni")')
    self.nl()

  def WriteTarget(self, target):
    # Skip cc_proto_lib targets.
    if isinstance(target, CcProtoLibTarget):
      return
    super().WriteTarget(target)

    if isinstance(target, CcLibTarget):
      self.WriteCcLibTarget(target)
    elif isinstance(target, ProtoLibTarget):
      self.WriteProtoLibTarget(target)
    else:
      raise NotImplementedError('I do not know how to write {}'.format(
          str(target)))

    self.nl()

  def GnDep(self, dep):
    if not dep.InTree():
      return dep.GetGnDep()

    target = self.GetTargetForInTreeDep(dep)

    # We don't generate CcProtoLibTargets, so we try to dereference them to
    # find the ProtoLibTarget in Tink base that they refer to.
    if isinstance(target, CcProtoLibTarget):
      return target.deps()[0].GetGnDep()

    if target in self._build_file:
      return ':{}'.format(target.name())
    if target.spec().startswith('//:'):
      return '{}:{}'.format(self._deps_prefix, target.spec()[3:])
    return '{}/{}'.format(self._deps_prefix, target.spec()[2:])

  def FormatValue(self, value):
    if isinstance(value, str):
      return '"{}"'.format(value)

    if isinstance(value, TargetRef):
      return '"{}"'.format(self.GnDep(value))

    raise Exception('I do not know how to write the {} value'.format(
        repr(value)))

  def WriteGnVariable(self, name, value):
    if isinstance(value, SetGnListValue):
      self.WriteGnSetListVariable(name, value)
      return
    if isinstance(value, RemoveGnListValue):
      self.WriteGnRemoveListVariable(name, value)
      return
    self.emitnl('{} = {}'.format(name, self.FormatValue(value)))

  def WriteGnListVariable(self, name, value, op):
    if len(value) == 0:
      return

    if len(value) == 1:
      single_line = '{} {} [ {} ]'.format(name, op, self.FormatValue(value[0]))
      if len(single_line) <= self._max_line:
        self.emitnl(single_line)
        return

    self.emitnl('{} {} ['.format(name, op))
    self.indent()

    for item in value:
      self.emitnl('{},'.format(self.FormatValue(item)))

    self.deindent()
    self.emitnl(']')

  def WriteGnSetListVariable(self, name, value):
    self.WriteGnListVariable(name, value, "=")

  def WriteGnRemoveListVariable(self, name, value):
    # Add and then remove the variable in case the var wasn't already added
    self.WriteGnListVariable(name, value, "+=")
    self.WriteGnListVariable(name, value, "-=")

  def WriteGnTarget(self, target_type, name, variables):
    self.emitnl('{}("{}") {{'.format(target_type, name))
    self.indent()
    for var, value in variables.items():
      self.WriteGnVariable(var, value)
    self.deindent()
    self.emitnl('}')
    pass

  def WriteProtoLibTarget(self, target):
    variables = GnVariables()
    variables['cc_generator_options'] = 'lite'
    variables['proto_in_dir'] = '//third_party/tink'
    variables['extra_configs'] = ['//third_party/tink:tink_config']
    variables['sources'] = sorted(target.srcs)
    variables['deps'] = target.deps()

    self.WriteGnTarget('proto_library', target.name(), variables)

  def WriteCcLibTarget(self, target):
    variables = GnVariables()
    variables['configs'] = RemoveGnListValue(['//build/config:no_rtti'])
    variables['sources'] = sorted(target.srcs + target.hdrs)
    variables['public_deps'] = target.deps()
    variables['public_configs'] = ['//third_party/tink:tink_config']

    self.WriteGnTarget('source_set', target.name(), variables)

def FetchTargets(targets, root_path, ignored_targets):
  graph = BuildGraph(root_path, ignored_targets)
  fetcher = TargetFetcher(graph, targets, error_on_unknown=True)
  targets = fetcher.FetchAll()
  print('Found {} targets.'.format(len(targets)))
  return targets, graph

def WriteTargetsToGn(targets, graph, root_path, deps_prefix):
  build_files = CreateBuildFiles(targets)
  gn_writer = GnWriter(
      rootdir=root_path,
      build_graph=graph,
      max_line=80,
      deps_prefix=deps_prefix)
  for f in build_files:
    gn_writer.WriteBuildFile(f)

def main(args):
  script_path = os.path.abspath(args[0])
  tools_path = os.path.dirname(script_path)
  tink_path = os.path.dirname(tools_path)
  cc_path = os.path.join(tink_path, 'cc')

  # Targets listed here will be ignored.
  ignored_targets = frozenset([])

  # Targets listed her are the start of the fetch. Put all the targets you plan
  # on directly depending upon here.
  targets = [
      '//hybrid:hybrid_config',
      '//hybrid:hybrid_decrypt_factory',
      '//hybrid:hybrid_encrypt_factory',
      '//hybrid:hybrid_key_templates',
      '//:binary_keyset_reader',
      '//:binary_keyset_writer',
      '//:cleartext_keyset_handle',
      '//:hybrid_decrypt',
      '//:hybrid_encrypt',
      '//:keyset_handle',
  ]
  targets, graph = FetchTargets(targets, cc_path, ignored_targets)
  WriteTargetsToGn(targets, graph, cc_path, '//third_party/tink/cc')

  # Targets listed here are the Tink ProtoLibTarget lives in the Tink base instead
  # of the CC WORKSPACE.
  # Attempt to fetch the ProtoLibTarget that the CcProtoLibTarget depends on.
  #
  # This attempt should be removed upon the proto src avaliable in the CC
  # WORKSPACE, i.e when Tink in Fuchsia is uprev to upstream/1.7.
  tink_base_targets = [
      '//proto:common_proto',
      '//proto:config_proto',
      '//proto:tink_proto',
      '//proto:aes_gcm_siv_proto',
      '//proto:hmac_proto',
      '//proto:kms_envelope_proto',
      '//proto:kms_aead_proto',
      '//proto:aes_eax_proto',
      '//proto:aes_gcm_proto',
      '//proto:aes_ctr_hmac_aead_proto',
      '//proto:aes_cmac_proto',
      '//proto:xchacha20_poly1305_proto',
      '//proto:ecdsa_proto',
      '//proto:ecies_aead_hkdf_proto',
  ]
  targets, graph = FetchTargets(tink_base_targets, tink_path, ignored_targets)
  WriteTargetsToGn(targets, graph, tink_path, '//third_party/tink')

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