#!/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 kazoo-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 //zircon/vdso
and building zircon, followed by uploading the changes to docs/ as a CL. (It
will attempt to do a build if it appears that definitions.json is out-of-date
with respect to the syscall fidl.)

It updates the signature, synopsis, and rights annotations, and corrects some
formatting.
"""

import argparse
import json
import os
import re
import subprocess
import sys

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

STANDARD_COMMENT = '<!-- Updated by update-docs-from-fidl, do not edit. -->'
STANDARD_BLOCK_HEADER = ['', STANDARD_COMMENT, '']

REFERENCES_COMMENT = \
        '<!-- References updated by update-docs-from-fidl, do not edit. -->'

SYSCALLS_FIDL_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, os.pardir,
                                                  'vdso'))


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, os.pardir,
                                         'out', 'default.zircon', 'gen',
                                         'include', 'zircon', 'syscalls',
                                         'definitions.json')),
                        help='path to kazoo .json output')
    parser.add_argument('--docroot',
                        default=os.path.normpath(
                            os.path.join(SCRIPT_DIR, os.pardir, os.pardir,
                                         'docs', 'reference', 'syscalls')),
                        help='root of syscalls/ to be updated')
    parser.add_argument(
        '--generate-missing',
        default=False,
        action="store_true",
        help='if set, generate stubs for any syscalls that are missing')
    parser.add_argument('name', nargs='*', help='only generate these syscalls')
    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', 'RIGHT1', 'and', 'have', 'RIGHT2', '.'],
        [
            'ARG', 'must', 'have', 'RIGHT1', 'and', 'have', 'RIGHT2', 'and',
            'have', 'RIGHT3', '.'
        ],
        [
            'ARG', 'must', 'have', 'RIGHT1', 'and', 'have', 'RIGHT2', 'and',
            'have', 'RIGHT3', 'and', 'have', 'RIGHT4', '.'
        ],
        ['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', 'TYPE', 'and', 'have', 'RIGHT',
            'or', 'have', 'RIGHT', '.'
        ],
        [
            'ARG', 'must', 'be', 'of', 'type', 'TYPE1', 'or', 'TYPE2', 'and',
            'have', 'RIGHT', '.'
        ],
        [
            'If', 'ARG', 'is', 'of', 'type', 'TYPE1', 'or', 'TYPE2', ',', 'it',
            'must', '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', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', 'and', 'have', 'RIGHT1', 'and', 'RIGHT2', '.'
        ],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'ARG2', 'must', 'be', 'of',
            'type', 'TYPE', 'and', 'have', 'RIGHT1', 'and', 'RIGHT2', 'and',
            'RIGHT3', '.'
        ],
        [
            'If', 'ARG1', '&', 'VALUE', ',', 'ARG2', 'must', 'be', 'of', 'type',
            'TYPE', 'and', 'have', 'RIGHT', '.'
        ],
        ['Every', 'entry', 'of', 'ARG', 'must', 'have', 'RIGHT', '.'],
        [
            'If', 'ARG1', 'is', 'VALUE', ',', 'affected', 'mappings', 'must',
            'be', 'writable', '.'
        ],
        [
            'Every', 'entry', 'of', 'ARG', 'must', 'have', 'a',
            'WAITITEMMEMBER', 'field', 'with', 'RIGHT', '.'
        ],

        # TODO(fxbug.dev/32253) 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_BTI',
        'ZX_OBJ_TYPE_CHANNEL',
        'ZX_OBJ_TYPE_CLOCK',
        'ZX_OBJ_TYPE_EVENT',
        'ZX_OBJ_TYPE_EVENTPAIR',
        'ZX_OBJ_TYPE_EXCEPTION',
        'ZX_OBJ_TYPE_FIFO',
        'ZX_OBJ_TYPE_GUEST',
        'ZX_OBJ_TYPE_INTERRUPT',
        'ZX_OBJ_TYPE_IOMMU',
        'ZX_OBJ_TYPE_JOB',
        'ZX_OBJ_TYPE_LOG',
        'ZX_OBJ_TYPE_MSI',
        'ZX_OBJ_TYPE_PAGER',
        'ZX_OBJ_TYPE_PCI_DEVICE',
        'ZX_OBJ_TYPE_PMT',
        'ZX_OBJ_TYPE_PORT',
        'ZX_OBJ_TYPE_PROCESS',
        'ZX_OBJ_TYPE_PROFILE',
        'ZX_OBJ_TYPE_RESOURCE',
        'ZX_OBJ_TYPE_SOCKET',
        'ZX_OBJ_TYPE_STREAM',
        'ZX_OBJ_TYPE_SUSPEND_TOKEN',
        'ZX_OBJ_TYPE_THREAD',
        'ZX_OBJ_TYPE_TIMER',
        'ZX_OBJ_TYPE_VCPU',
        'ZX_OBJ_TYPE_VMAR',
        'ZX_OBJ_TYPE_VMO',
    ])

    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(fxbug.dev/32253)', '']
    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('## ')) or
              line == REFERENCES_COMMENT):
            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, warn):
    desc = ''
    for x in syscall_data['top_description']:
        # TODO(scottmg): This is gross, we should change the output to give us a
        # string instead of tokens.
        if x in (',', '.', '-', '/', '\'', ')'):
            desc += x
        else:
            if desc and desc[-1] not in ('-', '/', '\'', '('):
                desc += ' '
            desc += x
    if not desc:
        desc = 'TODO(fxbug.dev/32938)'
    else:
        if desc[0].upper() != desc[0]:
            warn('short description (#^) should start with a capital')
        if desc[-1] != '.':
            warn('short description (#^) should end with a period')
    return STANDARD_BLOCK_HEADER + [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, warn)


def make_synopsis_block(syscall_data, warn):
    # Construct a synopsis block of the form:
    #
    #   ```c
    #   #include <zircon/syscalls.h>
    #
    #   zx_status_t zx_syscall_xxx(int32_t p1, int32_t p2);
    #   ```
    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 = ['```c'] + 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, os.pardir,
                                     'prebuilt', 'third_party', 'clang',
                                     'linux-x64', '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 generate_stub(md):
    """Makes a mostly-empty file that can then be filled out by later update
    functions."""

    stub = '''\
# zx_xyz

## NAME

## SYNOPSIS

## DESCRIPTION

TODO(fxbug.dev/32938)

## RIGHTS

## RETURN VALUE

TODO(fxbug.dev/32938)

## ERRORS

TODO(fxbug.dev/32938)

## SEE ALSO

TODO(fxbug.dev/32938)
'''
    with open(md, 'wb') as f:
        f.write(stub)


def check_for_orphans(syscalls, root):
    """Checks for any .md files that have been orphaned (no longer have an
    associated syscalls file entry.)
    """
    orphan_count = 0
    names = set([x['name'] for x in syscalls])
    for md in os.listdir(root):
        if md == '_toc.yaml':
            continue
        if md == 'README.md':
            continue
        if not md.endswith('.md'):
            print >> sys.stderr, 'warning: non .md file %s' % md
        name = md[:-3]
        if name not in names:
            orphan_count += 1
            print >> sys.stderr, 'warning: %s has no entry in syscalls' % md
    return orphan_count


# A few concept docs that are linked in SEE ALSO sections.
SEE_ALSO_CONCEPTS = {
    'clock transformations': '/docs/concepts/kernel/clock_transformations.md',
    'clocks': '/docs/reference/kernel_objects/clock.md',
    'exceptions': '/docs/concepts/kernel/exceptions.md',
    'futex objects': '/docs/reference/kernel_objects/futex.md',
    'rights': '/docs/concepts/kernel/rights.md',
    'timer slack': '/docs/concepts/kernel/timer_slack.md',
}


def make_see_also_block(referenced_syscalls, concepts, extra):
    """Makes a formatted SEE ALSO block given a list of syscall names.
    """
    result = []

    for concept in sorted(concepts):
        path = SEE_ALSO_CONCEPTS[concept]
        result.append(' - [' + concept + '](' + path + ')')

    for sc in sorted(referenced_syscalls):
        # References to these will be done later by update_syscall_references().
        result.append(' - [`zx_' + sc + '()`]')

    if extra:
        extra += ['']

    # No comment header here, because people are still editing this by hand,
    # we're only canonicalizing it.
    return [''] + extra + result + ['']


def update_seealso(lines, syscall, all_syscall_names, warn):
    """Rewrites 'SEE ALSO' block to canonical format.
    """
    start_index, end_index = find_block(lines, 'SEE ALSO')
    if start_index == -1:
        return

    referenced = set()
    concepts = set()
    extra = []
    for line in lines[start_index:end_index]:
        if not line or line == STANDARD_COMMENT:
            continue

        handled = False
        for concept in SEE_ALSO_CONCEPTS:
            if '[' + concept + ']' in line:
                concepts.add(concept)
                handled = True
        if handled:
            continue

        for sc in all_syscall_names:
            old = '[' + sc + ']'
            new = '[`zx_' + sc + '()`]'
            if old in line or new in line:
                referenced.add(sc)
                break
        else:
            warn('unrecognized "see also", keeping before syscalls: ' + line)
            extra.append(line)

    lines[start_index:end_index] = make_see_also_block(referenced, concepts,
                                                       extra)


SYSCALL_RE = {}


def update_syscall_references(lines, syscall, all_syscall_names, warn):
    """Attempts to update all syscall references to a canonical format, and
    linkifies them to their corresponding syscall.

    TODO(fxbug.dev/32938): It'd be nice to do the references from outside of
    docs/syscalls/ into syscalls too, in a similar style.
    """

    text = '\n'.join(lines)

    # Precompile these regexes as it takes measurable time.
    if not SYSCALL_RE:
        for sc in all_syscall_names:
            # Look for **zx_stuff()** and [`zx_stuff()`], with both "zx_" and
            # the () being optional.
            SYSCALL_RE[sc] = re.compile(r'\*{2}(?:zx_)?' + sc +
                                        r'(?:\(\))?\*{2}(?:\(\))?'
                                        r'|'
                                        r'(?:\[)`(?:zx_)?' + sc +
                                        r'(?:\(\))?`(?:\])?(\(\))?')

    referred_to = set()
    for sc in all_syscall_names:
        scre = SYSCALL_RE[sc]
        self = sc == syscall['name']
        repl = '`zx_' + sc + '()`'
        # Don't link to ourselves.
        if not self:
            repl = '[' + repl + ']'
        text, count = scre.subn(repl, text)
        if count and not self:
            referred_to.add(sc)

    lines[:] = text.splitlines()

    if REFERENCES_COMMENT not in lines:
        lines.extend(['', REFERENCES_COMMENT])
    start_index = lines.index(REFERENCES_COMMENT)

    references = []
    for ref in sorted(referred_to):
        references.append('[`zx_' + ref + '()`]: ' + ref + '.md')
    lines[start_index:] = [REFERENCES_COMMENT, ''] + references

    # Drop references section if it's empty to not be noisy.
    if lines[-3:] == ['', REFERENCES_COMMENT, '']:
        lines[:] = lines[:-3]


def build_if_out_of_date(syscalls_dir, json):
    """If the json file appears out-of-date relative to any files in the
    syscalls dir, then run a zircon build to get the definitions updated.
    """

    def is_up_to_date(input, output):
        """Checks if output exists and is newer-or-equal in mtime to input."""
        if not os.path.isfile(output):
            return False
        input_time = os.path.getmtime(input)
        output_time = os.path.getmtime(output)
        return output_time >= input_time

    for f in os.listdir(syscalls_dir):
        if not f.endswith('.fidl'):
            continue
        syscall = os.path.join(syscalls_dir, f)
        if not os.path.isfile(syscall):
            continue
        if not is_up_to_date(syscall, json):
            print('%s out of date vs %s, running `fx build`\n'
                  'This will only work if using out/default and configured'
                  ' for x64.' % (json, syscall))
            subprocess.check_call(['fx', 'build', '-C', 'out/default.zircon'])
            if not is_up_to_date(syscall, json):
                print '%s still out of date relative to %s!' % (json, syscall)
                raise SystemExit()
            break


def main():
    args = parse_args()
    inf = os.path.relpath(args.json)
    outf = os.path.relpath(args.docroot)
    build_if_out_of_date(os.path.relpath(SYSCALLS_FIDL_DIR), args.json)
    print 'using %s as input and updating %s...' % (inf, outf)
    data = json.loads(open(inf, 'rb').read())
    missing_count = 0
    all_syscall_names = set(x['name'] for x in data['syscalls'])
    for syscall in data['syscalls']:
        if 'internal' in syscall['attributes']:
            # Don't generate documentation for syscalls tagged as internal.
            continue
        name = syscall['name']
        if args.name and name not in args.name:
            continue
        md = os.path.join(outf, name + '.md')

        if not os.path.exists(md) and args.generate_missing:
            generate_stub(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)
            update_seealso(lines, syscall, all_syscall_names, warn)
            update_syscall_references(lines, syscall, all_syscall_names, 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
    missing_count += check_for_orphans(data['syscalls'], outf)
    return missing_count


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