#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""This script generates abseil.podspec from all BUILD.bazel files.

This is expected to run on abseil git repository with Bazel 1.0 on Linux.
It recursively analyzes BUILD.bazel files using query command of Bazel to
dump its build rules in XML format. From these rules, it constructs podspec
structure.
"""

import argparse
import collections
import os
import re
import subprocess
import xml.etree.ElementTree

# Template of root podspec.
SPEC_TEMPLATE = """
# This file has been automatically generated from a script.
# Please make modifications to `abseil.podspec.gen.py` instead.
Pod::Spec.new do |s|
  s.name     = 'abseil'
  s.version  = '${version}'
  s.summary  = 'Abseil Common Libraries (C++) from Google'
  s.homepage = 'https://abseil.io'
  s.license  = 'Apache License, Version 2.0'
  s.authors  = { 'Abseil Team' => 'abseil-io@googlegroups.com' }
  s.source = {
    :git => 'https://github.com/abseil/abseil-cpp.git',
    :tag => '${tag}',
  }
  s.module_name = 'absl'
  s.header_mappings_dir = 'absl'
  s.header_dir = 'absl'
  s.libraries = 'c++'
  s.compiler_flags = '-Wno-everything'
  s.pod_target_xcconfig = {
    'USER_HEADER_SEARCH_PATHS' => '$(inherited) "$(PODS_TARGET_SRCROOT)"',
    'USE_HEADERMAP' => 'NO',
    'ALWAYS_SEARCH_USER_PATHS' => 'NO',
  }
  s.ios.deployment_target = '9.0'
  s.osx.deployment_target = '10.10'
  s.tvos.deployment_target = '9.0'
  s.watchos.deployment_target = '2.0'
"""

# Rule object representing the rule of Bazel BUILD.
Rule = collections.namedtuple(
    "Rule", "type name package srcs hdrs textual_hdrs deps visibility testonly")


def get_elem_value(elem, name):
  """Returns the value of XML element with the given name."""
  for child in elem:
    if child.attrib.get("name") != name:
      continue
    if child.tag == "string":
      return child.attrib.get("value")
    if child.tag == "boolean":
      return child.attrib.get("value") == "true"
    if child.tag == "list":
      return [nested_child.attrib.get("value") for nested_child in child]
    raise "Cannot recognize tag: " + child.tag
  return None


def normalize_paths(paths):
  """Returns the list of normalized path."""
  # e.g. ["//absl/strings:dir/header.h"] -> ["absl/strings/dir/header.h"]
  return [path.lstrip("/").replace(":", "/") for path in paths]


def parse_rule(elem, package):
  """Returns a rule from bazel XML rule."""
  return Rule(
      type=elem.attrib["class"],
      name=get_elem_value(elem, "name"),
      package=package,
      srcs=normalize_paths(get_elem_value(elem, "srcs") or []),
      hdrs=normalize_paths(get_elem_value(elem, "hdrs") or []),
      textual_hdrs=normalize_paths(get_elem_value(elem, "textual_hdrs") or []),
      deps=get_elem_value(elem, "deps") or [],
      visibility=get_elem_value(elem, "visibility") or [],
      testonly=get_elem_value(elem, "testonly") or False)


def read_build(package):
  """Runs bazel query on given package file and returns all cc rules."""
  result = subprocess.check_output(
      ["bazel", "query", package + ":all", "--output", "xml"])
  root = xml.etree.ElementTree.fromstring(result)
  return [
      parse_rule(elem, package)
      for elem in root
      if elem.tag == "rule" and elem.attrib["class"].startswith("cc_")
  ]


def collect_rules(root_path):
  """Collects and returns all rules from root path recursively."""
  rules = []
  for cur, _, _ in os.walk(root_path):
    build_path = os.path.join(cur, "BUILD.bazel")
    if os.path.exists(build_path):
      rules.extend(read_build("//" + cur))
  return rules


def relevant_rule(rule):
  """Returns true if a given rule is relevant when generating a podspec."""
  return (
      # cc_library only (ignore cc_test, cc_binary)
      rule.type == "cc_library" and
      # ignore empty rule
      (rule.hdrs + rule.textual_hdrs + rule.srcs) and
      # ignore test-only rule
      not rule.testonly)


def get_spec_var(depth):
  """Returns the name of variable for spec with given depth."""
  return "s" if depth == 0 else "s{}".format(depth)


def get_spec_name(label):
  """Converts the label of bazel rule to the name of podspec."""
  assert label.startswith("//absl/"), "{} doesn't start with //absl/".format(
      label)
  # e.g. //absl/apple/banana -> abseil/apple/banana
  return "abseil/" + label[7:]


def write_podspec(f, rules, args):
  """Writes a podspec from given rules and args."""
  rule_dir = build_rule_directory(rules)["abseil"]
  # Write root part with given arguments
  spec = re.sub(r"\$\{(\w+)\}", lambda x: args[x.group(1)],
                SPEC_TEMPLATE).lstrip()
  f.write(spec)
  # Write all target rules
  write_podspec_map(f, rule_dir, 0)
  f.write("end\n")


def build_rule_directory(rules):
  """Builds a tree-style rule directory from given rules."""
  rule_dir = {}
  for rule in rules:
    cur = rule_dir
    for frag in get_spec_name(rule.package).split("/"):
      cur = cur.setdefault(frag, {})
    cur[rule.name] = rule
  return rule_dir


def write_podspec_map(f, cur_map, depth):
  """Writes podspec from rule map recursively."""
  for key, value in sorted(cur_map.items()):
    indent = "  " * (depth + 1)
    f.write("{indent}{var0}.subspec '{key}' do |{var1}|\n".format(
        indent=indent,
        key=key,
        var0=get_spec_var(depth),
        var1=get_spec_var(depth + 1)))
    if isinstance(value, dict):
      write_podspec_map(f, value, depth + 1)
    else:
      write_podspec_rule(f, value, depth + 1)
    f.write("{indent}end\n".format(indent=indent))


def write_podspec_rule(f, rule, depth):
  """Writes podspec from given rule."""
  indent = "  " * (depth + 1)
  spec_var = get_spec_var(depth)
  # Puts all files in hdrs, textual_hdrs, and srcs into source_files.
  # Since CocoaPods treats header_files a bit differently from bazel,
  # this won't generate a header_files field so that all source_files
  # are considered as header files.
  srcs = sorted(set(rule.hdrs + rule.textual_hdrs + rule.srcs))
  write_indented_list(
      f, "{indent}{var}.source_files = ".format(indent=indent, var=spec_var),
      srcs)
  # Writes dependencies of this rule.
  for dep in sorted(rule.deps):
    name = get_spec_name(dep.replace(":", "/"))
    f.write("{indent}{var}.dependency '{dep}'\n".format(
        indent=indent, var=spec_var, dep=name))


def write_indented_list(f, leading, values):
  """Writes leading values in an indented style."""
  f.write(leading)
  f.write((",\n" + " " * len(leading)).join("'{}'".format(v) for v in values))
  f.write("\n")


def generate(args):
  """Generates a podspec file from all BUILD files under absl directory."""
  rules = filter(relevant_rule, collect_rules("absl"))
  with open(args.output, "wt") as f:
    write_podspec(f, rules, vars(args))


def main():
  parser = argparse.ArgumentParser(
      description="Generates abseil.podspec from BUILD.bazel")
  parser.add_argument(
      "-v", "--version", help="The version of podspec", required=True)
  parser.add_argument(
      "-t",
      "--tag",
      default=None,
      help="The name of git tag (default: version)")
  parser.add_argument(
      "-o",
      "--output",
      default="abseil.podspec",
      help="The name of output file (default: abseil.podspec)")
  args = parser.parse_args()
  if args.tag is None:
    args.tag = args.version
  generate(args)


if __name__ == "__main__":
  main()
