#!/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',
            '.'
        ],
        [
            '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 is_special_and_warn(syscall_data, what, warn):
    name = syscall_data['name']
    # TODO(ZX-2399): These files multiplex multiple functions into one doc. I'm
    # not sure if this is worth it, but don't break them for now.
    if name in ('channel_read', 'object_get_property', 'object_signal'):
        warn('not updating ' + what + ' for special file')
        return True
    return False


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.
    """
    if is_special_and_warn(syscall_data, 'name', warn):
        return

    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):
    header = [
        '```',
        '#include <zircon/syscalls.h>',
        '',
    ]

    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

    to_format = (
        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


# TODO(ZX-2399): This is a temporary worklist as each is manually audited. Many
# argument names between syscalls.abigen and the existing documentation differ,
# which makes the hand written DESCRIPTION block wrong if they're changed. This
# will be deleted once all can be generated.
synopsis_whitelist = (
    'bti_create',
    'bti_pin',
    'bti_release_quarantine',
    'channel_create',
    'channel_write',
    'clock_get_monotonic',
    'cprng_draw',
    'deadline_after',
    'event_create',
    'eventpair_create',
    'fifo_create',
    'guest_create',
    'handle_close',
    'handle_close_many',
    'handle_duplicate',
    'handle_replace',
    'interrupt_ack',
    'interrupt_bind_vcpu',
    'interrupt_destroy',
    'interrupt_trigger',
    'interrupt_wait',
    'nanosleep',
    'object_get_child',
    'object_get_cookie',
    'object_set_cookie',
    'object_set_property',
    'object_wait_async',
    'object_wait_one',
    'pmt_unpin',
    'port_create',
    'process_create',
    'process_start',
    'socket_create',
    'socket_read',
    'socket_shutdown',
    'socket_write',
    'system_get_num_cpus',
    'system_get_version',
    'task_kill',
    'thread_create',
    'timer_cancel',
    'timer_set',
    'vmar_allocate',
    'vmo_clone',
    'vmo_create',
    'vmo_create_physical',
    'vmo_get_size',
    'vmo_op_range',
    'vmo_read',
    'vmo_set_cache_policy',
    'vmo_set_size',
    'vmo_write',
)


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, warn):
    """Updates the main title of the .md file given by |filename|.
    """
    if is_special_and_warn(syscall_data, 'title', warn):
        return

    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)
            if name in synopsis_whitelist:
                update_synopsis(lines, syscall, warn)
            else:
                warn('not in synopsis_whitelist')
            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())
