#!/usr/bin/env python

# Copyright 2015 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This script will update Skia's dependencies as necessary and run
# gyp if needed.

# Depends on: Python, Git, and depot_tools.
#
# Example usage:
#
#   git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
#   export PATH="${PWD}/depot_tools:${PATH}"
#   git clone https://skia.googlesource.com/skia
#   cd skia
#   python bin/sync-and-gyp
#   ninja -C out/Debug && out/Debug/dm
#
# Once changes are made to DEPS or gyp/ or the source, call:
#
#   python bin/sync-and-gyp

# To retreive and use all optional deps:
#
#   python bin/sync-and-gyp --deps=all
#   ninja -C out/Debug && out/Debug/dm

import fnmatch
import hashlib
import os
import subprocess
import sys

skia_dir = os.path.join(os.path.dirname(__file__), os.pardir)

skia_opt_deps = [arg for arg in sys.argv[1:] if arg.startswith('--deps=')]

skia_out = os.environ.get("SKIA_OUT")
if skia_out:
  skia_out = os.path.abspath(skia_out)
  hash_path = os.path.join(skia_out, 'gyp_hash')
else:
  hash_path = os.path.join('out', 'gyp_hash')

os.chdir(skia_dir)

if not os.path.isfile('DEPS'):
  sys.stderr.write('DEPS file missing')
  exit(1)

deps_hasher = hashlib.sha1()
with open('DEPS', 'r') as f:
  deps_hasher.update(f.read())
deps_hasher.update(repr(skia_opt_deps))
deps_hash = deps_hasher.hexdigest()
current_deps_hash = None
if os.path.isfile('.deps_sha1'):
  with open('.deps_sha1', 'r') as f:
    current_deps_hash = f.read().strip()

default_gclient_config = '''
solutions = [
  { "name"        : ".",
    "url"         : "https://skia.googlesource.com/skia.git",
    "deps_file"   : "DEPS",
    "managed"     : False,
    "custom_deps" : {
    },
    "safesync_url": "",
  },
]
cache_dir = None
'''

# Must use gclient.bat rather than gclient on windows (at least on mingw)
gclient = 'gclient'
if sys.platform == 'win32' or sys.platform == 'cygwin':
  gclient = 'gclient.bat'

if current_deps_hash != deps_hash:
  # `gclient sync` is very slow, so skip whenever we can.
  try:
    subprocess.call([gclient, '--version'])
  except:
    sys.stdout.write('gclient missing from $PATH, please install ' +
                     'depot_tools\n    https://skia.org/user/quick/desktop\n')
    exit(1)
  if not os.path.isfile('.gclient'):
    with open('.gclient', 'w') as o:
      o.write(default_gclient_config)
  gclient_sync_command = [gclient, 'sync'] + skia_opt_deps
  try:
    sys.stdout.write('%r\n' % gclient_sync_command)
    subprocess.check_call(gclient_sync_command)
  except:
    sys.stderr.write('\n`gclient sync` failed.\n')
    try:
      os.remove('.deps_sha1')  # Unknown state.
    except:
      pass
    exit(1)
  # Only write hash after a successful sync.
  with open('.deps_sha1', 'w') as o:
    o.write(deps_hash)

hasher = hashlib.sha1()

for var in ['AR', 'AR_host', 'AR_target',
            'CC', 'CC_host', 'CC_target',
            'CFLAGS', 'CFLAGS_host',
            'CPPFLAGS', 'CPPFLAGS_host',
            'CXX', 'CXX_host', 'CXX_target',
            'GYP_DEFINES', 'GYP_GENERATORS',
            'NM', 'NM_host', 'NM_target',
            'READELF', 'READELF_host', 'READELF_target']:
  hasher.update(os.environ.get(var, '') + '\n')

def listfiles(folder, matchfilter):
  for root, folders, files in os.walk(folder):
    for filename in files:
      if fnmatch.fnmatch(filename, matchfilter):
        yield os.path.join(root, filename)

for filename in sorted(listfiles('gyp', '*')):
  with open(filename, 'r') as f:
    hasher.update(f.read())

for dir in ['bench', 'gm', 'tests']:
  for filename in sorted(listfiles(dir, '*.c*')):
    hasher.update(filename + '\n')

gyp_hash = hasher.hexdigest()

def cat_if_exists(path):
  if os.path.exists(path):
    with open(path, 'r') as f:
      return f.read()
  return ''

if cat_if_exists(hash_path).strip() != gyp_hash:
  env = os.environ.copy()
  if skia_out:
    env['SKIA_OUT'] = skia_out
  subprocess.call(['python', './gyp_skia'], env=env)
  with open(hash_path, 'w') as o:
    o.write(gyp_hash)
