#! /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 CMakeTargetNameFromInTreeSpec(spec):
  dirname, name = ParseTargetSpec(spec)
  head = dirname
  path_list = [name]
  while head != '':
    head, tail = os.path.split(head)
    path_list.insert(0, tail)
  return '_'.join(path_list)


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))
    target = self.RemapTarget(target)
    assert (isinstance(target, Target))
    self._targets[target.spec()] = target

  def RemapTarget(self, target):
    # CMake does not like it if a cc_library has headers in a subdir. So we
    # move the target.
    if not isinstance(target, CcLibTarget):
      return target

    dirnames = [os.path.dirname(hdr) for hdr in target.hdrs]
    if not any(d != '' for d in dirnames):
      return target

    if not all(d != '' for d in dirnames):
      raise Exception(
          'I do not know how to deal with targets that have some headers and sources in a subdirectory and some not: '
          + target.spec)

    if not all(d == dirnames[0] for d in dirnames):
      raise Exception(
          'I do not know how to deal with targets that have headers and sources in different subdirectories: '
          + target.spec)

    subdir = dirnames[0]

    old_spec = target.spec()
    dirpath = os.path.join(target.dirpath(), subdir)
    name = target.name()
    sort_id = target.sort_id()
    deps = target.deps()
    srcs = [os.path.relpath(src, subdir) for src in target.srcs]
    hdrs = [os.path.relpath(hdr, subdir) for hdr in target.hdrs]
    target = CcLibTarget(dirpath, name, sort_id, deps, srcs=srcs, hdrs=hdrs)

    new_spec = target.spec()

    self._spec_map_old_to_new[old_spec] = new_spec

    for t in self._targets.values():
      t.RemapDep(old_spec, new_spec)

    return 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):
    return '//{}:{}'.format(self._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'

  def GetCMakeDep(self):
    spec = self.spec()
    suffix = '_proto'
    if not spec.endswith(suffix):
      raise Exception('Unexpected name for proto_library: ' + self.spec())
    spec = spec[:-len(suffix)] + '_lib'

    return CMakeTargetNameFromInTreeSpec(spec)


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'

  def GetCMakeDep(self):
    return CMakeTargetNameFromInTreeSpec(self.spec())


##############################################################
# 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)

  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 == '@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)

  raise Exception('I do not know how to deal with this dep: "{}"'.format(dep))


class TargetRef(object):

  def InTree(self):
    return False


class PathTargetRef(TargetRef):

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

  def name(self):
    return self._name

  def spec(self):
    return '//{}:{}'.format(self._dirpath, self._name)

  def dirpath(self):
    return self._dirpath

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


class InTreeTargetRef(PathTargetRef):

  def InTree(self):
    return True


class AbslTargetRef(PathTargetRef):

  def GetCMakeDep(self):
    return '::'.join(self._dirpath.split('/'))

  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 GetCMakeDep(self):
    return 'protobuf_lite'

  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 GetCMakeDep(self):
    return self._name

  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 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())
    # We don't generate CcProtoLibTargets, so we try to dereference them to
    # find the ProtoLibTarget that they refer to.
    if isinstance(target, CcProtoLibTarget):
      assert (len(target.deps()) == 1)
      target = self._build_graph.GetTarget(target.deps()[0].spec())
      assert (isinstance(target, ProtoLibTarget))
    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.'
    ])

  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 CMakeWriter(BuildFileWriter):

  def __init__(self, rootdir, target_prefix, build_graph, max_line):
    super().__init__(
        rootdir=rootdir, build_graph=build_graph, max_line=max_line)
    self._target_prefix = target_prefix

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

  def SingleLineFunction(self, func, *args):
    return '{}({})'.format(func, ' '.join(args))

  def WriteFunction(self, func, *args):
    single = self.SingleLineFunction(func, *args)
    if len(single) <= self._max_line:
      self.emitnl(single)
      return

    self.emitnl('{}('.format(func))
    self.indent()

    for arg in args:
      self.emitnl(arg)

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

  def WriteHeader(self):
    super().WriteHeader()
    self.nl()
    for subdir in self._build_file.subdirs:
      self.WriteFunction('add_subdirectory', subdir)
    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)
      return
    if isinstance(target, ProtoLibTarget):
      self.WriteProtoLibTarget(target)
      return
    raise NotImplementedError('I do not know how to write {}'.format(
        str(target)))

  def WriteLibTargetDeps(self, target):
    name = self.TargetName(target)
    in_tree_deps = [self.DepName(dep) for dep in target.deps() if dep.InTree()]
    deps = [self.DepName(dep) for dep in target.deps()]

    if in_tree_deps:
      self.WriteFunction('add_dependencies', name, *in_tree_deps)
    if deps:
      self.WriteFunction('target_link_libraries', name, *deps)

  def WriteCcLibTarget(self, target):
    name = self.TargetName(target)
    self.WriteFunction('add_library', name, *target.hdrs, *target.srcs)
    if not target.srcs:
      self.WriteFunction('set_target_properties', name, 'PROPERTIES',
                         'LINKER_LANGUAGE', 'CXX')
    if target.hdrs:
      self.WriteFunction('tink_export_hdrs', *target.hdrs)
    self.WriteLibTargetDeps(target)
    self.nl()

  def WriteProtoLibTarget(self, target):
    name = self.TargetName(target)
    srcs = []
    for src in target.srcs:
      suffix = '.proto'
      if not src.endswith(suffix):
        raise Exception('Unexpected name {} for proto in {}'.format(
            src, target.spec()))
      srcs.append(src[:-len(suffix)])
    hdrs_out = name.upper() + '_PROTO_HDRS'
    self.WriteFunction('tink_make_protobuf_cpp_lib', name, hdrs_out, *srcs)
    self.WriteLibTargetDeps(target)
    self.nl()

  def TargetName(self, target):
    return self._target_prefix + '_' + target.GetCMakeDep()

  def DepName(self, dep):
    if dep.InTree():
      target = self.GetTargetForInTreeDep(dep)
      return self._target_prefix + '_' + target.GetCMakeDep()
    return dep.GetCMakeDep()


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)
    if target in self._build_file:
      return ':{}'.format(target.name())
    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 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 her are the start of the fetch. Put all the targets you plan
  # on directly depending upon here.
  targets = [
      '//cc/hybrid:hybrid_config',
      '//cc/hybrid:hybrid_decrypt_factory',
      '//cc/hybrid:hybrid_encrypt_factory',
      '//cc/hybrid:hybrid_key_templates',
      '//cc:binary_keyset_reader',
      '//cc:binary_keyset_writer',
      '//cc:cleartext_keyset_handle',
      '//cc:hybrid_decrypt',
      '//cc:hybrid_encrypt',
      '//cc:keyset_handle',
  ]
  # Targets listed here will be ignored.
  ignored_targets = frozenset([])
  graph = BuildGraph(tink_path, ignored_targets)
  fetcher = TargetFetcher(graph, targets, error_on_unknown=True)
  targets = fetcher.FetchAll()
  print('Found {} targets.'.format(len(targets)))
  build_files = CreateBuildFiles(targets)
  gn_writer = GnWriter(
      rootdir=tink_path,
      build_graph=graph,
      max_line=80,
      deps_prefix='//third_party/tink')
  for f in build_files:
    gn_writer.WriteBuildFile(f)


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