#!/usr/bin/env python3
"""
Compares previous output of all kazoo generation with current output.

The current golden state (vs. real syscalls) is saved in golden.txt.

A `cp` command will be printed to update golden.txt if the current
pipeline generates different output than previously checked in.
"""

import argparse
import datetime
import os
import shutil
import subprocess
import sys

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
GOLDEN = os.path.abspath(os.path.join(os.path.dirname(__file__), 'golden.txt'))


def parse_args():
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('--builddir',
                        help='build root to which rsp files are relative',
                        required=True)
    parser.add_argument('--fidlc',
                        help='rspfile containing fidlc binary',
                        required=True)
    parser.add_argument('--kazoo',
                        help='rspfile containing kazoo binary',
                        required=True)
    parser.add_argument('--syscalls',
                        help='path to syscalls',
                        default=os.path.normpath(
                            os.path.join(SCRIPT_DIR, os.pardir, os.pardir,
                                         'vdso')))
    parser.add_argument('--p4merge',
                        action='store_true',
                        help='open diffs in p4merge if changes')
    parser.add_argument('--output-touch',
                        help='file to touch on success',
                        required=True)
    parser.add_argument('--tmp-base',
                        help='location to use for temporary files',
                        required=True)
    return parser.parse_args()


def generate_fidlc_json(fidlc_binary, syscall_dir, output_fidlc_json_path):
    fidl_files = []
    with os.scandir(syscall_dir) as it:
        for entry in it:
            if (not entry.name.startswith('.') and entry.is_file() and
                    entry.name.endswith('.fidl')):
                fidl_files.append(os.path.join(syscall_dir, entry.name))

    subprocess.check_call(
        [fidlc_binary, '--json', output_fidlc_json_path, '--files'] +
        sorted(fidl_files))


def build_golden(input_files, output_combined):
    with open(output_combined, 'wb') as outf:
        for filename in input_files:
            outf.write(('----- %s START -----\n' % os.path.basename(filename)).encode('utf-8'))
            outf.write(open(filename, 'rb').read())
            outf.write(('----- %s END -----\n\n\n' % os.path.basename(filename)).encode('utf-8'))


def generate_kazoo_outputs(kazoo_binary, fidlc_json_path, all_output_styles,
                           output_dir):

    def guess_ext(style):
        if style in ('go-vdso-arm64-calls', 'go-vdso-x86-calls'):
            return 's'
        if style.startswith('go'):
            return 'go'
        if style == 'rust':
            return 'rs'
        if style == 'json':
            return 'json'
        return 'h'

    style_args = []
    files = []
    for style in all_output_styles:
        filename = '%s.%s' % (os.path.join(output_dir, style), guess_ext(style))
        files.append(filename)
        style_args.append('--%s=%s' % (style, filename))
    subprocess.check_call([kazoo_binary] + style_args + [fidlc_json_path])
    return files


def read_rsp_and_rebase(path, builddir):
    with open(path, 'r') as f:
        from_rsp = f.read().strip()
        return os.path.join(builddir, from_rsp)


def main():
    args = parse_args()

    tmp_json = os.path.join(args.tmp_base, 'syscalls.json')
    fidlc = read_rsp_and_rebase(args.fidlc, args.builddir)
    generate_fidlc_json(fidlc, args.syscalls, tmp_json)

    tmp_kazoo_dir = os.path.join(args.tmp_base, 'kazoo-outputs')
    try:
        shutil.rmtree(tmp_kazoo_dir)
    except:
        pass
    os.makedirs(tmp_kazoo_dir)

    all_styles = (
        'c-ulib-header',
        'category',
        'go-syscall-arm64-asm',
        'go-syscall-stubs',
        'go-syscall-x86-asm',
        'go-vdso-arm64-calls',
        'go-vdso-keys',
        'go-vdso-x86-calls',
        'json',
        'kernel-header',
        'kernel-wrappers',
        'private-header',
        'public-header',
        'rust',
        'syscall-numbers',
        'testonly-public-header',
    )
    kazoo = read_rsp_and_rebase(args.kazoo, args.builddir)
    files = generate_kazoo_outputs(kazoo, tmp_json, all_styles, tmp_kazoo_dir)

    tmp_golden = os.path.join(args.tmp_base, 'new-golden.txt')
    build_golden(files, tmp_golden)
    rc = subprocess.call(['diff', GOLDEN, tmp_golden])
    if rc != 0:
        print('CHANGES DETECTED IN SYSCALL OUTPUT')
        print()
        print('Please run:')
        print('  cp %s %s' % (tmp_golden, GOLDEN))
        print('to acknowledge these changes.')
        print()
        print('Files can be found locally in %s for inspection.' %
              tmp_kazoo_dir)
        if args.p4merge:
            subprocess.call(['p4merge', GOLDEN, tmp_golden])
    else:
        with open(args.output_touch, 'w') as f:
            f.write(str(datetime.datetime.utcnow()))
    return rc


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