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

import json
import md5
import multiprocessing
import os
import shutil
import sys
import tempfile
import urllib
import urllib2

from subprocess import check_call, check_output

assert '/' in [os.sep, os.altsep] and os.pardir == '..'

ASSETS = 'platform_tools/android/apps/skqp/src/main/assets'
BUCKET = 'skia-skqp-assets'

def make_skqp_model(arg):
    name, urls, exe = arg
    tmp = tempfile.mkdtemp()
    for url in urls:
        urllib.urlretrieve(url, tmp + '/' + url[url.rindex('/') + 1:])
    check_call([exe, tmp, ASSETS + '/gmkb/' + name])
    shutil.rmtree(tmp)
    sys.stdout.write(name + ' ')
    sys.stdout.flush()

def goldgetter(meta, exe):
    assert os.path.exists(exe)
    jobs = []
    for rec in meta:
        urls = [d['URL'] for d in rec['digests']
                if d['status'] == 'positive' and
                (set(d['paramset']['config']) & set(['vk', 'gles']))]
        if urls:
            jobs.append((rec['testName'], urls, exe))
    pool = multiprocessing.Pool(processes=20)
    pool.map(make_skqp_model, jobs)
    sys.stdout.write('\n')
    return set((n for n, _, _ in jobs))

def gold(first_commit, last_commit):
    c1, c2 = (check_output(['git', 'rev-parse', c]).strip()
            for c in (first_commit, last_commit))
    f = urllib2.urlopen('https://public-gold.skia.org/json/export?' + urllib.urlencode([
        ('fbegin', c1),
        ('fend', c2),
        ('query', 'config=gles&config=vk&source_type=gm'),
        ('pos', 'true'),
        ('neg', 'false'),
        ('unt', 'false')
    ]))
    j = json.load(f)
    f.close()
    return j

def gset(path):
    s = set()
    if os.path.isfile(path):
        with open(path, 'r') as f:
            for line in f:
                s.add(line.strip())
    return s

def make_rendertest_list(models, good, bad):
    assert good.isdisjoint(bad)
    do_score = good & models
    no_score = bad | (good - models)
    to_delete = models & bad
    for d in to_delete:
        path = ASSETS + '/gmkb/' + d
        if os.path.isdir(path):
            shutil.rmtree(path)
    results = dict()
    for n in do_score:
        results[n] = 0
    for n in no_score:
        results[n] = -1
    return ''.join('%s,%d\n' % (n, results[n]) for n in sorted(results))

def get_digest(path):
    m = md5.new()
    with open(path, 'r') as f:
        m.update(f.read())
    return m.hexdigest()

def upload_cmd(path, digest):
    return ['gsutil', 'cp', path, 'gs://%s/%s' % (BUCKET, digest)]

def upload_model():
    bucket_url = 'gs://%s/' % BUCKET
    extant = set((u.replace(bucket_url, '', 1)
                  for u in check_output(['gsutil', 'ls', bucket_url]).splitlines() if u))
    cmds = []
    filelist = []
    for dirpath, _, filenames in os.walk(ASSETS + '/gmkb'):
        for filename in filenames:
            path = os.path.join(dirpath, filename)
            digest = get_digest(path)
            if digest not in extant:
                cmds.append(upload_cmd(path, digest))
            filelist.append('%s;%s\n' % (digest, os.path.relpath(path, ASSETS)))
    tmp = tempfile.mkdtemp()
    filelist_path = tmp + '/x'
    with open(filelist_path, 'w') as o:
        for l in filelist:
            o.write(l)
    filelist_digest = get_digest(filelist_path)
    if filelist_digest not in extant:
        cmds.append(upload_cmd(filelist_path, filelist_digest))

    pool = multiprocessing.Pool(processes=20)
    pool.map(check_call, cmds)
    shutil.rmtree(tmp)
    return filelist_digest

def remove(x):
    if os.path.isdir(x) and not os.path.islink(x):
        shutil.rmtree(x)
    if os.path.exists(x):
        os.remove(x)

def main(first_commit, last_commit):
    check_call(upload_cmd('/dev/null', get_digest('/dev/null')))

    os.chdir(os.path.dirname(__file__) + '/../..')
    remove(ASSETS + '/files.checksum')
    for d in [ASSETS + '/gmkb', ASSETS + '/skqp', ]:
        remove(d)
        os.mkdir(d)

    check_call([sys.executable, 'tools/git-sync-deps'],
               env=dict(os.environ, GIT_SYNC_DEPS_QUIET='T'))
    build = 'out/ndebug'
    check_call(['bin/gn', 'gen', build,
                '--args=cc="clang" cxx="clang++" is_debug=false'])
    check_call(['ninja', '-C', build,
                'jitter_gms', 'list_gpu_unit_tests', 'make_skqp_model'])

    models = goldgetter(gold(first_commit, last_commit), build + '/make_skqp_model')

    check_call([build + '/jitter_gms', 'tools/skqp/bad_gms.txt'])

    with open(ASSETS + '/skqp/rendertests.txt', 'w') as o:
        o.write(make_rendertest_list(models, gset('good.txt'), gset('bad.txt')))

    remove('good.txt')
    remove('bad.txt')

    with open(ASSETS + '/skqp/unittests.txt', 'w') as o:
        o.write(check_output([build + '/list_gpu_unit_tests']))

    with open(ASSETS + '/files.checksum', 'w') as o:
        o.write(upload_model() + '\n')

    sys.stdout.write(ASSETS + '/files.checksum\n')
    sys.stdout.write(ASSETS + '/skqp/rendertests.txt\n')
    sys.stdout.write(ASSETS + '/skqp/unittests.txt\n')

if __name__ == '__main__':
    if len(sys.argv) != 3:
        sys.stderr.write('Usage:\n  %s C1 C2\n\n' % sys.argv[0])
        sys.exit(1)
    main(sys.argv[1], sys.argv[2])
