#!/usr/bin/env python
#
# Copyright 2016 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function

import collections
import json
import os
import subprocess
import sys

# Finds all public sources in include directories then write them to skia.h.

# Also write skia.h.deps, which Ninja uses to track dependencies. It's the
# very same mechanism Ninja uses to know which .h files affect which .cpp files.

gn              = sys.argv[1]
absolute_source = sys.argv[2]
skia_h          = sys.argv[3]
include_dirs    = sys.argv[4:]

absolute_source = os.path.normpath(absolute_source)

include_dirs = [os.path.join(os.path.normpath(include_dir), '')
                for include_dir in include_dirs]
include_dirs.sort(key=len, reverse=True)

gn_desc_cmd = [gn, 'desc', '.', '--root=%s' % absolute_source, '--format=json',
               '*']

desc_json_txt = ''
try:
  desc_json_txt = subprocess.check_output(gn_desc_cmd).decode('utf-8')
except subprocess.CalledProcessError as e:
  print(e.output.decode('utf-8'))
  raise

desc_json = {}
try:
  desc_json = json.loads(desc_json_txt)
except ValueError:
  print(desc_json_txt)
  raise

sources = set()

for target in desc_json.values():
  # We'll use `public` headers if they're listed, or pull them from `sources`
  # if not.  GN sneaks in a default "public": "*" into the JSON if you don't
  # set one explicitly.
  search_list = target.get('public')
  if search_list == '*':
    search_list = target.get('sources', [])

  for name in search_list:
    sources.add(os.path.join(absolute_source, os.path.normpath(name[2:])))

Header = collections.namedtuple('Header', ['absolute', 'include'])
headers = {}
for source in sources:
  source_as_include = [os.path.relpath(source, absolute_source)
                       for include_dir in include_dirs
                       if source.startswith(include_dir)]
  if not source_as_include:
    continue
  statinfo = os.stat(source)
  key = str(statinfo.st_ino) + ':' + str(statinfo.st_dev)
  # On Windows os.stat st_ino is 0 until 3.3.4 and st_dev is 0 until 3.4.0.
  if key == '0:0':
    key = source
  include_path = source_as_include[0]
  if key not in headers or len(include_path) < len(headers[key].include):
    headers[key] = Header(source, include_path)

headers = sorted(headers.values(), key=lambda x: x.include)

with open(skia_h, 'w') as f:
  f.write('// skia.h generated by GN.\n')
  f.write('#ifndef skia_h_DEFINED\n')
  f.write('#define skia_h_DEFINED\n')
  for header in headers:
    f.write('#include "' + header.include + '"\n')
  f.write('#endif//skia_h_DEFINED\n')

with open(skia_h + '.deps', 'w') as f:
  f.write(skia_h + ':')
  for header in headers:
    f.write(' ' + header.absolute)
  f.write(' build.ninja.d')
  f.write('\n')

# Temporary: during development this file wrote skia.h.d, not skia.h.deps,
# and I think we have some bad versions of those files laying around.
if os.path.exists(skia_h + '.d'):
  os.remove(skia_h + '.d')
