#!/usr/bin/env python

# Copyright 2018 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
"""
This tool uses the contents of the abigen-generated syscalls/definitions.json
to update docs/syscalls/.

It is not run automatically as part of the build for now (to allow confirmation
of what it does). So it should be run manually after updating syscalls.abigen
and building zircon, followed by uploading the changes to docs/ as a CL.

Currently, it only updates the rights annotations, but in the future it should
update the signature, arguments, etc. too.
"""

import argparse
import json
import os
import subprocess
import sys

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))

STANDARD_BLOCK_HEADER = [
    '', '<!-- Updated by scripts/update-docs-from-abigen, '
    'do not edit this section manually. -->', ''
]


def parse_args():
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument(
        '--json',
        default=os.path.normpath(
            os.path.join(SCRIPT_DIR, os.pardir, 'build-x64', 'gen', 'global',
                         'include', 'zircon', 'syscalls', 'definitions.json')),
        help='path to abigen .json output')
    parser.add_argument(
        '--docroot',
        default=os.path.normpath(
            os.path.join(SCRIPT_DIR, os.pardir, 'docs', 'syscalls')),
        help='root of docs/syscalls/ to be updated')
    return parser.parse_args()


def break_into_sentences(stream):
    """Partition on '.' to break into chunks. '.' can't appear elsewhere
    in the input stream."""
    sentences = []
    cur = []
    for tok in stream:
        cur.append(tok)
        if tok == '.':
            sentences.append(cur)
            cur = []
    assert not cur, cur
    return sentences


def match_sentence_form(sentence, arg_names):
    """Matches a known sentence form, returning a format string and a dict for
    substitution. The values in dict are converted to markdown format.

    Certain TERMINALS are special:
    - ARG must appear in arg_names
    - RIGHT must be a valid ZX_RIGHT_
    - TYPE must be a valid ZX_OBJ_TYPE_
    - RSRC must be a valid ZX_RSRC_KIND_

    VALUE is a generic unchecked value type, used for masks, options, etc.
    """
    sentence_forms = [
        ['None', '.'],
        ['ARG', 'must', 'have', 'RIGHT', '.'],
        ['ARG', 'must', 'have', 'resource', 'kind', 'RSRC', '.'],
        ['ARG', 'must', 'be', 'of', 'type', 'TYPE', '.'],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE', 'and', 'have', 'RIGHT1',
            'and', 'have', 'RIGHT2', '.'
        ],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE', 'and', 'have', 'RIGHT',
            '.'
        ],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE1', 'or', 'TYPE2', 'and', 'have', 'RIGHT',
            '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'have', 'RIGHT',
            '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'have',
            'resource', 'kind', 'RSRC', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', 'and', 'have', 'RIGHT', '.'
        ],
        [
            'If', 'ARG1', '&', 'VALUE', ',', 'ARG2', 'must', 'be', 'of', 'type',
            'TYPE', 'and', 'have', 'RIGHT', '.'
        ],
        ['Every', 'entry', 'of', 'ARG', 'must', 'have', 'RIGHT', '.'],
        [
            'Every', 'entry', 'of', 'ARG', 'must', 'have', 'a',
            'WAITITEMMEMBER', 'field', 'with', 'RIGHT', '.'
        ],

        # TODO(ZX-2399) TODO(scottmg): This is a hack specifically for
        # zx_channel_call_args_t. Trying to make a pseudo-generic case (that
        # handles the length from wr_num_handles, etc.) for this doesn't seem
        # worth the trouble at the moment, since it's only checking that the
        # handles have TRANSFER anyway. Revisit if/when there's more instances
        # like this.
        ['All', 'wr_handles', 'of', 'ARG', 'must', 'have', 'RIGHT', '.'],
    ]

    all_rights = set([
        'ZX_RIGHT_NONE',
        'ZX_RIGHT_DUPLICATE',
        'ZX_RIGHT_TRANSFER',
        'ZX_RIGHT_READ',
        'ZX_RIGHT_WRITE',
        'ZX_RIGHT_EXECUTE',
        'ZX_RIGHT_MAP',
        'ZX_RIGHT_GET_PROPERTY',
        'ZX_RIGHT_SET_PROPERTY',
        'ZX_RIGHT_ENUMERATE',
        'ZX_RIGHT_DESTROY',
        'ZX_RIGHT_SET_POLICY',
        'ZX_RIGHT_GET_POLICY',
        'ZX_RIGHT_SIGNAL',
        'ZX_RIGHT_SIGNAL_PEER',
        'ZX_RIGHT_WAIT',
        'ZX_RIGHT_INSPECT',
        'ZX_RIGHT_MANAGE_JOB',
        'ZX_RIGHT_MANAGE_PROCESS',
        'ZX_RIGHT_MANAGE_THREAD',
        'ZX_RIGHT_APPLY_PROFILE',
    ])

    all_types = set([
        'ZX_OBJ_TYPE_PROCESS',
        'ZX_OBJ_TYPE_THREAD',
        'ZX_OBJ_TYPE_VMO',
        'ZX_OBJ_TYPE_CHANNEL',
        'ZX_OBJ_TYPE_EVENT',
        'ZX_OBJ_TYPE_PORT',
        'ZX_OBJ_TYPE_INTERRUPT',
        'ZX_OBJ_TYPE_PCI_DEVICE',
        'ZX_OBJ_TYPE_LOG',
        'ZX_OBJ_TYPE_SOCKET',
        'ZX_OBJ_TYPE_RESOURCE',
        'ZX_OBJ_TYPE_EVENTPAIR',
        'ZX_OBJ_TYPE_JOB',
        'ZX_OBJ_TYPE_VMAR',
        'ZX_OBJ_TYPE_FIFO',
        'ZX_OBJ_TYPE_GUEST',
        'ZX_OBJ_TYPE_VCPU',
        'ZX_OBJ_TYPE_TIMER',
        'ZX_OBJ_TYPE_IOMMU',
        'ZX_OBJ_TYPE_BTI',
        'ZX_OBJ_TYPE_PROFILE',
        'ZX_OBJ_TYPE_PMT',
        'ZX_OBJ_TYPE_SUSPEND_TOKEN',
        'ZX_OBJ_TYPE_PAGER',
    ])

    all_rsrcs = set([
        'ZX_RSRC_KIND_MMIO',
        'ZX_RSRC_KIND_IRQ',
        'ZX_RSRC_KIND_IOPORT',
        'ZX_RSRC_KIND_HYPERVISOR',
        'ZX_RSRC_KIND_ROOT',
        'ZX_RSRC_KIND_VMEX',
        'ZX_RSRC_KIND_SMC',
    ])

    # There's only two structs in zircon/types.h, so hardcoding this here is
    # a bit stinky, but probably OK.
    members_of_zx_wait_item_t = set([
        'handle',
        'waitfor',
        'pending',
    ])

    for form in sentence_forms:
        result_fmt = ''
        result_values = {}
        for f, s in zip(form, sentence):
            # Literal match.
            if s == f:
                if f == '.' or f == ',' or f == '->':
                    result_fmt += f
                elif f == '[':
                    result_fmt += '\['
                else:
                    result_fmt += ' ' + f
            elif f.startswith('ARG'):
                if s not in arg_names:
                    break
                else:
                    result_values[f] = '*' + s + '*'
                    result_fmt += ' %(' + f + ')s'
            elif f.startswith('VALUE'):
                # TODO(scottmg): Worth checking these in some way?
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('RIGHT'):
                if s not in all_rights:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('RSRC'):
                if s not in all_rsrcs:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('TYPE'):
                if s not in all_types:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '**' + s + '**'
            elif f.startswith('WAITITEMMEMBER'):
                if s not in members_of_zx_wait_item_t:
                    break
                result_fmt += ' %(' + f + ')s'
                result_values[f] = '*' + s + '*'
            else:
                break
        else:
            if result_fmt[0] == ' ':
                result_fmt = result_fmt[1:]
            return result_fmt, result_values
    else:
        return None, None


def to_markdown(req, arguments, warn):
    """Parses a few known forms of rules (see match_sentence_forms).

    Converts |req| to formatted markdown.
    """
    sentences = break_into_sentences(req)

    if not sentences:
        rights = ['TODO(ZX-2399)', '']
    else:
        rights = []
    for sentence in sentences:
        match_fmt, match_values = match_sentence_form(
            sentence, [x['name'] for x in arguments])
        if not match_fmt:
            warn('failed to parse: ' + repr(sentence))
            raise SystemExit(1)
        else:
            rights.append(match_fmt % match_values)
            rights.append('')

    return STANDARD_BLOCK_HEADER + rights


def find_block(lines, name):
    """Finds a .md block with the given name, and returns (start, end) line
    indices.
    """
    start_index = -1
    end_index = -1
    for i, line in enumerate(lines):
        if line == '## ' + name:
            start_index = i + 1
        elif start_index >= 0 and line.startswith('## '):
            end_index = i
            break
    return start_index, end_index


def update_rights(lines, syscall_data, warn):
    """Updates the RIGHTS block of the .md file in lines.
    """
    rights_start_index, rights_end_index = find_block(lines, 'RIGHTS')
    if rights_start_index == -1 or rights_end_index == -1:
        warn('did not find RIGHTS section, skipping update')
        return

    lines[rights_start_index:rights_end_index] = to_markdown(
        syscall_data['requirements'], syscall_data['arguments'], warn)


def make_name_block(syscall_data):
    start = syscall_data['name'] + ' - '
    desc = ''
    for x in syscall_data['top_description']:
        # TODO(scottmg): This is gross, we should change the abigen parser to
        # give us a string instead of tokens.
        if x in (',', '.', '-', '/', '\'', ')'):
            desc += x
        else:
            if desc and desc[-1] not in ('-', '/', '\'', '('):
                desc += ' '
            desc += x
    return STANDARD_BLOCK_HEADER + [start + desc, '']


def update_name(lines, syscall_data, warn):
    """Updates the NAME block of the .md file in lines.
    """
    name_start_index, name_end_index = find_block(lines, 'NAME')
    if name_start_index == -1 or name_end_index == -1:
        warn('did not find NAME section, skipping update')
        return

    lines[name_start_index:name_end_index] = make_name_block(syscall_data)


def make_synopsis_block(syscall_data, warn):
    headers = set([
        '#include <zircon/syscalls.h>',
    ])
    extra_headers = {}
    for arg in syscall_data['arguments']:
        if arg['type'] == 'zx_port_packet_t':
            headers.add('#include <zircon/syscalls/port.h>')
        elif (arg['type'] == 'zx_smc_parameters_t' or
              arg['type'] == 'zx_smc_result_t'):
            headers.add('#include <zircon/syscalls/smc.h>')
    header = ['```'] + sorted(list(headers)) + ['']

    def format_arg(x):
        ret = ''
        if 'IN' in x['attributes']:
            ret += 'const '
        if x['type'] == 'any':
            ret += 'void '
        else:
            ret += x['type'] + ' '
        if x['is_array']:
            ret += ' * '
        ret += ' ' + x['name']
        return ret

    no_return = ''
    if 'noreturn' in syscall_data['attributes']: no_return = '[[noreturn]]'

    to_format = (no_return + syscall_data['return_type'] + ' zx_' +
                 syscall_data['name'] + '(')
    args = ','.join(format_arg(x) for x in syscall_data['arguments'])
    if not args:
        args = 'void'
    to_format += args + ');'

    CLANG_FORMAT_PATH = os.path.join(SCRIPT_DIR, os.pardir, 'prebuilt',
                                     'downloads', 'clang', 'bin',
                                     'clang-format')
    clang_format = subprocess.Popen([
        CLANG_FORMAT_PATH,
        '-style={BasedOnStyle: Google, BinPackParameters: false}'
    ],
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE)
    formatted, _ = clang_format.communicate(to_format)
    if clang_format.returncode != 0:
        warn('formatting synopsis failed, skipping update')
        return None

    footer = [
        '```',
        '',
    ]
    return STANDARD_BLOCK_HEADER + header + [formatted] + footer


def update_synopsis(lines, syscall_data, warn):
    """Updates the SYNOPSIS block of the .md file in lines.
    """
    start_index, end_index = find_block(lines, 'SYNOPSIS')
    if start_index == -1 or end_index == -1:
        warn('did not find SYNOPSIS section, skipping update')
        return

    syn = make_synopsis_block(syscall_data, warn)
    if not syn:
        return
    lines[start_index:end_index] = syn


def update_title(lines, syscall_data, _):
    """Updates the main title of the .md file given by |filename|.
    """
    correct_title = '# zx_' + syscall_data['name']
    if lines[0] != correct_title:
        lines[0] = correct_title


def main():
    args = parse_args()
    inf = os.path.relpath(args.json)
    outf = os.path.relpath(args.docroot)
    print 'using %s as input and updating %s...' % (inf, outf)
    data = json.loads(open(inf, 'rb').read())
    missing_count = 0
    for syscall in data['syscalls']:
        name = syscall['name']
        md = os.path.join(outf, name + '.md')
        if not os.path.exists(md):
            print >> sys.stderr, (
                'warning: %s not found for updating, skipping update' % md)
            missing_count += 1
        else:
            with open(md, 'rb') as f:
                lines = f.read().splitlines()

            assert (lines)

            def warn(msg):
                print >> sys.stderr, 'warning: %s: %s' % (md, msg)

            update_title(lines, syscall, warn)
            update_name(lines, syscall, warn)
            update_synopsis(lines, syscall, warn)
            update_rights(lines, syscall, warn)

            with open(md, 'wb') as f:
                f.write('\n'.join(lines) + '\n')

    if missing_count > 0:
        print >> sys.stderr, 'warning: %d missing .md files' % missing_count
    return missing_count


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