#!/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, 'w') as outf:
        for filename in input_files:
            outf.write('----- %s START -----\n' % os.path.basename(filename))
            outf.write(open(filename, 'r').read())
            outf.write('----- %s END -----\n\n\n' % os.path.basename(filename))


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())
