#!/usr/bin/env python3.8
# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import os
import re
import sys
import textwrap
from pathlib import Path
from string import Template

# Output target paths that may be modified.
FUCHSIA_DIR = Path(os.environ["FUCHSIA_DIR"])
FIDL_DOCS_ROOT_DIR = FUCHSIA_DIR / "docs/development/languages/fidl"
EXAMPLE_CODE_BASE_DIR = FUCHSIA_DIR / "examples/fidl/new"
EXAMPLE_DOCS_BASE_DIR = FIDL_DOCS_ROOT_DIR / "examples"
CONCEPT_DOCS_BASE_DIR = FIDL_DOCS_ROOT_DIR / "concepts"
DOCS_TOC_YAML_FILE = FIDL_DOCS_ROOT_DIR / "_toc.yaml"
DOCS_ROOT_README_FILE = EXAMPLE_DOCS_BASE_DIR / "README.md"
CODE_ROOT_BUILD_GN_FILE = EXAMPLE_CODE_BASE_DIR / "BUILD.gn"

# Template source paths.
TEMPLATES_DIR = FUCHSIA_DIR / "tools/fidl/scripts/canonical_example/templates"
CREATE_CODE_NEW_TEMPLATES_DIR = TEMPLATES_DIR / "create_code_new"
CREATE_CODE_VARIANT_TEMPLATES_DIR = TEMPLATES_DIR / "create_code_variant"
CREATE_DOCS_NEW_TEMPLATES_DIR = TEMPLATES_DIR / "create_docs_new"
CREATE_DOCS_VARIANT_TEMPLATES_DIR = TEMPLATES_DIR / "create_docs_variant"
DOCUMENT_CONCEPT_TEMPLATES_DIR = TEMPLATES_DIR / "document_concept"
DOCUMENT_WIDGET_TEMPLATES_DIR = TEMPLATES_DIR / "document_widget"

# Startup-compiled regexes.
REGEX_IS_PASCAL_CASE = re.compile(r"^(?:[A-Z][a-z0-9]+)+$")
REGEX_IS_SNAKE_CASE = re.compile(r"^[a-z][a-z0-9_]+$")
REGEX_TO_SNAKE_CASE = re.compile(r"([A-Z]+)")
REGEX_TO_TEXT_CASE = re.compile(r"_+")

# Other important defaults.
BASELINE = "baseline"
DNS = "DO" + "NOT" + "SUBMIT"
DNRC = "DO_NOT_REMOVE_COMMENT"
BINDINGS = {
    "cpp_natural": "main.cc",
    "cpp_wire": "main.cc",
    "hlcpp": "main.cc",
    "rust": "src/main.rs",
}

# Comment guard patterns for various file types.
COMMENT_GUARDS = {
    ".cc": ("// ", ""),
    ".gn": ("# ", ""),
    ".md": ("<!-- ", " -->"),
    ".rs": ("// ", ""),
}


# Custom exceptions.
class AlreadyExistsError(Exception):
    pass


class InputError(Exception):
    pass


class StepError(Exception):
    pass


def is_pascal_case(input):
    """Check if a string is PascalCase, aka (upper) CamelCase
    """
    return REGEX_IS_PASCAL_CASE.match(input)


def is_snake_case(input):
    """Check if a string is snake_case.
    """
    return REGEX_IS_SNAKE_CASE.match(input)


def to_flat_case(input):
    """Converts a snake_case string to (lower) camelCase, ex "iamflatcase".
    """
    return input.replace("_", "")


def to_snake_case(input):
    """Converts a PascalCase string to snake_case, ex "i_am_snake_case".
    """
    return re.sub(REGEX_TO_SNAKE_CASE, r"_\1", input).lower()


def to_sentence_case(input):
    """Converts a snake_case string to a sentence case text case string, ex "I am sentence case".
    """
    return to_text_case(input).capitalize()


def to_text_case(input):
    """Converts a snake_case string to an all lowercase text case string, ex "i am text case".
    """
    return re.sub(REGEX_TO_TEXT_CASE, " ", input)


def build_subs(series, variant, protocol, bug):
    """Builds the substitution map.
    """
    if not is_snake_case(series):
        raise InputError("Expected series '%s' to be snake_case" % series)
    if not is_snake_case(variant):
        raise InputError("Expected variant '%s' to be snake_case" % variant)
    if protocol and not is_pascal_case(protocol):
        raise InputError("Expected protocol '%s' to be pascal_case" % protocol)
    if bug and not (isinstance(bug, int) and bug > 0):
        raise InputError("Expected bug '%s' to be an unsigned integer" % bug)

    if not protocol:
        protocol = ""

    # LINT.IfChange
    return {
        'bug': "%s" % bug if bug else "",
        'dns': DNS,
        'protocol_pascal_case': protocol,
        'protocol_snake_case': to_snake_case(protocol),
        'series_flat_case': to_flat_case(series),
        'series_sentence_case': to_sentence_case(series),
        'series_snake_case': series,
        'series_text_case': to_text_case(series),
        'variant_flat_case': to_flat_case(variant),
        'variant_snake_case': variant,
    }
    # LINT.ThenChange(/tools/fidl/scripts/canonical_example/README.md)


def build_doc_subs(series, variant):
    """Builds the substitution map, but ignores `protocol` and `bug`.
    """
    return build_subs(series, variant, None, None)


def get_dns_count(input):
    """Count `TODO(DNS)` occurrences.
    """
    return input.count("TODO(%s)" % DNS)


def apply_subs(subdir, subs, source, target):
    """Apply substitutions to templates located in the source dir, and write them to the target dir.

    Returns a dict of paths to numbers, wih the number representing the count of outstanding DNS
    TODOs in the file.
    """
    dns_counts = {}
    for path, subdirs, files in os.walk(source):
        for file_name in files:
            # Process the filename, including doing any substitutions necessary.
            temp_path = os.path.join(path, file_name)
            rel_path = os.path.relpath(
                temp_path[:temp_path.rindex('.')], source)
            out_path = target / subdir / Template(
                str(rel_path)).substitute(subs)

            # Do substitutions on the file text as well.
            out_contents = ""
            with open(temp_path, 'r') as f:
                out_contents = Template(f.read()).substitute(subs)

            # Count DNS occurrences.
            dns_counts[str(out_path)] = get_dns_count(out_contents)

            # Do the actual file writes.
            os.makedirs(os.path.dirname(out_path), exist_ok=True)
            with open(out_path, "wt") as f:
                f.write(out_contents)

    return dns_counts


def lines_between_dnrc_tags(lines, src_path, identifier=""):
    """Take a list of lines, and return the sub-list between the DNRC tags.

    Returns the selected lines, plus the index at which they are located in the source file.
    """
    if identifier:
        identifier = ":" + identifier
    REGEX_OPEN_DNRC = re.compile("\\sDO_NOT_REMOVE_COMMENT%s" % identifier)
    REGEX_CLOSE_DNRC = re.compile("\\s\/DO_NOT_REMOVE_COMMENT%s" % identifier)

    opened = -1
    for line_num, line in enumerate(lines):
        if opened >= 0:
            if REGEX_CLOSE_DNRC.search(line):
                return opened + 1, line_num
        elif REGEX_OPEN_DNRC.search(line):
            opened = line_num

    if opened < 0:
        raise InputError(
            "Closing /DO_NOT_REMOVE_COMMENT comment missing from '%s'" %
            src_path)
    raise InputError(
        "DO_NOT_REMOVE_COMMENT comment missing from '%s'" % src_path)


def validate_entry_does_not_already_exist(needle, files):
    """Check to see if a canonical example series already exists anywhere we want to insert it.

    For each validated file, return a three-tuple containing all the lines of the file, the start,
    and end of the range covered by the `DO_NOT_REMOVE_COMMENT` tags.
    """
    ranges = {}
    for path, identifier in files.items():
        # Find `DO_NOT_REMOVE_COMMENT` and `/DO_NOT_REMOVE_COMMENT`
        lines = []
        with open(path, 'r') as f:
            lines = f.readlines()
            start, end = lines_between_dnrc_tags(lines, path, identifier)

        # Does the needle appear anywhere in between those bounds?
        for line in lines:
            if needle in line:
                raise AlreadyExistsError(
                    "An entry for '%s' already exists in '%s'" % (needle, path))

        ranges[path] = (lines, start, end)
    return ranges


def validate_todo_md_still_exists(series, variant, subdir):
    """Ensure that TODO.md for the implementation we are about to begin is still there.

    This file being missing indicate corrupt state.
    """
    # Validate that the TODO.md file is still where we expect it - if not, this step may have
    # already been completed.
    todo_md_file_path = EXAMPLE_CODE_BASE_DIR / series / variant / subdir / "TODO.md"
    if not os.path.exists(todo_md_file_path):
        raise StepError(
            "Cannot scaffold the %s implementation for '%s/%s' because the TODO.md is missing"
            % (subdir, series, variant))


def resolve_create_templates(subs, source_to_target_map):
    """Do all of the raw copying necessary to create a canonical example variant.

    Returns a dict of paths to numbers, wih the number representing the count of outstanding DNS
    TODOs in the created files.
    """
    # Copy over each doc template file, processing substitutions on both file names and contents as
    # we go.
    dns_counts = {}
    for source, target in source_to_target_map.items():
        for path, count in apply_subs(subs['series_snake_case'], subs, source,
                                      target).items():
            dns_counts[path] = count
    return dns_counts


def resolve_document_templates(subs):
    """Do all of the raw copying necessary to document a single concept.

    Returns a dict of paths to numbers, wih the number representing the count of outstanding DNS
    TODOs in the file.
    """
    dns_counts = {}
    source_to_subdir_map = {
        DOCUMENT_CONCEPT_TEMPLATES_DIR: "concepts",
        DOCUMENT_WIDGET_TEMPLATES_DIR: "widgets",
    }
    for source, subdir in source_to_subdir_map.items():
        for path, count in apply_subs(subdir, subs, source,
                                      FIDL_DOCS_ROOT_DIR).items():
            dns_counts[path] = count
    return dns_counts


def create_variant(series, variant, protocol, bug):
    """Create a canonical example series variant.

    Returns a dict of paths to numbers, wih the number representing the count of outstanding DNS
    TODOs in the file.
    """
    # Build the substitution dictionary.
    subs = build_subs(series, variant, protocol, bug)

    # Make sure the baseline case exists. Also specifically validate that the baseline FIDL
    # definition and top-level docs README both exist, as we will need to modify them directly.
    series_root_gn_file_path = EXAMPLE_CODE_BASE_DIR / series / "BUILD.gn"
    baseline_code_dir_path = EXAMPLE_CODE_BASE_DIR / series / "baseline"
    series_docs_dir_path = EXAMPLE_DOCS_BASE_DIR / series
    baseline_fidl_file_path = baseline_code_dir_path / "fidl" / (
        "%s.test.fidl" % series)
    series_docs_readme_path = series_docs_dir_path / "README.md"
    if not os.path.exists(baseline_code_dir_path):
        raise StepError(
            "Cannot create variant '%s' because its baseline source directory %s does not exist"
            % (variant, baseline_code_dir_path))
    if not os.path.exists(series_docs_dir_path):
        raise StepError(
            "Cannot create variant '%s' because its series example docs directory %s does not exist"
            % (variant, series_docs_dir_path))
    if not os.path.exists(baseline_fidl_file_path):
        raise StepError(
            "Cannot create variant '%s' because its baseline FIDL file %s does not exist"
            % (variant, baseline_fidl_file_path))

    if not os.path.exists(series_root_gn_file_path):
        raise StepError(
            "Cannot create variant '%s' because its series BUILD.gn file %s does not exist"
            % (variant, series_root_gn_file_path))
    series_gn_dnrc_lines = validate_entry_does_not_already_exist(
        "%s:tests" % variant,
        {series_root_gn_file_path: ''})[series_root_gn_file_path]

    if not os.path.exists(series_docs_readme_path):
        raise StepError(
            "Cannot create variant '%s' because its series README.md file %s does not exist"
            % (variant, series_docs_readme_path))
    readme_dnrc_lines = validate_entry_does_not_already_exist(
        "{#%s}" % variant,
        {series_docs_readme_path: ''})[series_docs_readme_path]

    # Create the raw variant. We'll follow this up by replacing the "raw" FIDL file with a copy
    # of the one from the baseline case.
    dns_counts = resolve_create_templates(
        subs, {
            CREATE_DOCS_VARIANT_TEMPLATES_DIR: EXAMPLE_DOCS_BASE_DIR,
            CREATE_CODE_VARIANT_TEMPLATES_DIR: EXAMPLE_CODE_BASE_DIR,
        })

    # Copy the FIDL definition from the baseline case, and update the dns count so the user is aware
    # that they need to make further edits.
    variant_fidl_file_path = EXAMPLE_CODE_BASE_DIR / series / variant / "fidl" / (
        "%s.test.fidl" % series)
    with open(baseline_fidl_file_path, "r") as f:
        # Replace the ".baseline" library name suffix with this variant's name.
        lines = f.readlines()
        for i in range(len(lines)):
            if lines[i].startswith("library"):
                lines[i] = lines[i].replace(
                    BASELINE, subs['variant_flat_case'], 1)
                break

        # Add a DNS to the end of the file.
        lines.append(
            textwrap.dedent(
                """
                // TODO(%s): Modify this FIDL to reflect the changes explored by this variant.
                """ % DNS))

        # Overwrite the raw FIDL file with this transformed baseline version, and update the dns
        # count so the user is aware that they need to make further edits in this file.
        out_contents = "".join(lines)
        dns_counts[str(variant_fidl_file_path)] = get_dns_count(out_contents)
        with open(variant_fidl_file_path, "wt") as f:
            f.write(out_contents)

    # Add an entry to the root BUILD.gn file for this series.
    with open(series_root_gn_file_path, "wt") as f:
        lines, start, end = series_gn_dnrc_lines
        lines.insert(end, """    "%s:tests",\n""" % variant)
        f.write("".join(lines))

    # Add an entry to the root docs README.md file's example section for this series, and update the
    # dns count so the user is aware that they need to make further edits in this file.
    with open(series_docs_readme_path, "wt") as f:
        lines, start, end = readme_dnrc_lines
        lines.insert(end, """<<_%s_tutorial.md>>\n\n""" % variant)
        lines.insert(
            end,
            """### <!-- TODO(%s): Add title -->{#%s}\n\n""" % (DNS, variant))
        out_contents = "".join(lines)
        dns_counts[str(series_docs_readme_path)] = get_dns_count(out_contents)
        f.write(out_contents)

    return dns_counts


def create_new(series, protocol, bug):
    """Create a new canonical example series.

    Returns a dict of paths to numbers, wih the number representing the count of outstanding DNS
    TODOs in the file.
    """
    # Build the substitution dictionary.
    subs = build_subs(series, BASELINE, protocol, bug)

    # Do a first pass through the files we'll be editing, to ensure that they are in a good state.
    edit_ranges = validate_entry_does_not_already_exist(
        series, {
            DOCS_TOC_YAML_FILE: '',
            DOCS_ROOT_README_FILE: 'examples',
            CODE_ROOT_BUILD_GN_FILE: '',
        })

    # Update the _toc.yaml file to include an entry pointing to this canonical example series.
    with open(DOCS_TOC_YAML_FILE, "wt") as f:
        lines, start, end = edit_ranges[DOCS_TOC_YAML_FILE]
        lines.insert(
            end,
            """    path: /docs/development/languages/fidl/examples/%s/README.md\n"""
            % series)
        lines.insert(
            end, """  - title: "%s"\n""" % subs['series_sentence_case'])
        f.write("".join(lines))

    # Update the root README to include this series.
    with open(DOCS_ROOT_README_FILE, "wt") as f:
        lines, start, end = edit_ranges[DOCS_ROOT_README_FILE]
        lines.insert(
            end,
            """## %s\n\n<!-- TODO(fxbug.dev/%s): DOCUMENT[%s/%s] (brief description) -->\n\n"""
            % (
                subs['series_sentence_case'], subs['bug'],
                subs['series_snake_case'], subs['variant_snake_case']))
        f.write("".join(lines))

    # Update /examples/fidl/new/BUILD.gn to support this series.
    with open(CODE_ROOT_BUILD_GN_FILE, "wt") as f:
        lines, start, end = edit_ranges[CODE_ROOT_BUILD_GN_FILE]
        lines.insert(end, """    "%s:tests",\n""" % subs['series_snake_case'])
        f.write("".join(lines))

    # Copy over each doc template file, processing substitutions on both file names and contents as
    # we go.
    dns_counts = resolve_create_templates(
        subs, {
            CREATE_DOCS_NEW_TEMPLATES_DIR: EXAMPLE_DOCS_BASE_DIR,
            CREATE_DOCS_VARIANT_TEMPLATES_DIR: EXAMPLE_DOCS_BASE_DIR,
            CREATE_CODE_NEW_TEMPLATES_DIR: EXAMPLE_CODE_BASE_DIR,
            CREATE_CODE_VARIANT_TEMPLATES_DIR: EXAMPLE_CODE_BASE_DIR,
        })

    return dns_counts


def create(name, protocol, bug, series):
    """Create a new variant in a canonical example series.

    Can create an entirely new series or simply extend an existing one.
    """
    dns_counts = {}
    if series:
        dns_counts = create_variant(series, name, protocol, bug)
    else:
        dns_counts = create_new(name, protocol, bug)

    report_success(dns_counts)


def document(name, concepts):
    """Generate documentation instructions for an already-created canonical example variant.
    """
    # Validate that the variant already exists. The name argument can refer to either a series'
    # baseline case or a named variant, so try both options.
    series = ""
    variant = ""
    for outer in os.listdir(EXAMPLE_DOCS_BASE_DIR):
        maybe_dir = os.path.join(str(EXAMPLE_DOCS_BASE_DIR), outer)
        if os.path.isdir(maybe_dir):
            if outer == name:
                series = name
                variant = BASELINE
                break
            else:
                for inner in os.listdir(maybe_dir):
                    if inner.startswith("_%s" % name):
                        series = outer
                        variant = name
                        break
    if not (series and variant):
        raise StepError(
            "Cannot find already created variant '%s' to document" % name)

    # Validate that the root docs README.md file exists, and that its concepts section is well
    # marked, since we will need to modify it.
    readme_concepts_lines = validate_entry_does_not_already_exist(
        "### %s" % variant,
        {DOCS_ROOT_README_FILE: 'concepts'})[DOCS_ROOT_README_FILE]

    # Build the substitution dictionary. We don't need to do protocol or bug number substitution, so
    # ignore those arguments.
    subs = build_doc_subs(series, variant)

    # Create the files for each concept.
    dns_counts = {}
    for concept in sorted(concepts, reverse=True):
        subs['concept_snake_case'] = concept
        subs['concept_sentence_case'] = to_sentence_case(concept)

        # Add an entry to the root docs README.md file's example section for this concept, and update
        # the dns count so the user is aware that they need to make further edits in this file.
        with open(DOCS_ROOT_README_FILE, "wt") as f:
            prefix = "<<../widgets/_"
            lines, start, end = readme_concepts_lines
            line_num = start
            while line_num < end:
                line = lines[line_num]
                if line.startswith(prefix) and concept < line[len(prefix):]:
                    break
                line_num = line_num + 1
            lines.insert(line_num, """%s%s.md>>\n\n""" % (prefix, concept))
            out_contents = "".join(lines)
            f.write(out_contents)

        # Now generate the actual file from a template.
        for path, count in resolve_document_templates(subs).items():
            dns_counts[path] = count

    # Replace documentation TODOs generated in the create step with DNS ones.
    REGEX_DOCUMENT_TODO = re.compile(
        "TODO\\(fxbug.dev\\/\\d+\\): DOCUMENT\\[%s\\/%s]" % (series, variant))
    possible_add_doc_files = [
        DOCS_ROOT_README_FILE,
        EXAMPLE_DOCS_BASE_DIR / series / "README.md",
        EXAMPLE_DOCS_BASE_DIR / series / ("_%s_tutorial.md" % variant),
    ]
    for path in possible_add_doc_files:
        with open(path, "r") as f:
            path_str = str(path)
            replaced, count = re.subn(
                REGEX_DOCUMENT_TODO, "TODO(%s):" % DNS, f.read())
            if dns_counts.get(path_str):
                dns_counts[path_str] = dns_counts[path_str] + count
            else:
                dns_counts[path_str] = count
            with open(path, "wt") as f:
                f.write(replaced)

    report_success(dns_counts)


def copy_baseline_implementation(series, variant, subdir, subs):
    """
    """
    dns_counts = {}
    series_code_root_path = EXAMPLE_CODE_BASE_DIR / series
    baseline_impl_root_path = series_code_root_path / "baseline" / subdir
    variant_impl_root_path = series_code_root_path / variant / subdir

    # Loop through the baseline files. For each file, perform a number of replacements to swap the
    # word "baseline" with the variant name we are looking at.
    for path, subdirs, files in os.walk(baseline_impl_root_path):
        for file_name in files:
            # Process the filename to be in the variant's, rather than baseline's, directory.
            src_path = Path(os.path.join(path, file_name))
            out_path = Path(
                str(src_path).replace(
                    str(baseline_impl_root_path), str(variant_impl_root_path),
                    1))
            ext = src_path.suffix
            (comment_start, comment_end) = COMMENT_GUARDS[ext]

            with open(src_path, "r") as f:
                contents = f.read()

                # We need to do very different replacement operations depending on whether or not
                # this is a gn file.
                if ext == ".gn":
                    # No DNS at the end of the file, and do one replacement each for strings where
                    # series and variant are split by "/" and "_".
                    dns = ""
                    contents = contents.replace(
                        "%s/%s" % (subs['series_snake_case'], "baseline"),
                        "%s/%s" %
                        (subs['series_snake_case'], subs['variant_snake_case']))
                    contents = contents.replace(
                        "%s_%s" % (subs['series_flat_case'], "baseline"),
                        "%s_%s" %
                        (subs['series_flat_case'], subs['variant_flat_case']))
                    contents = contents.replace(
                        ".baseline", "." + subs['variant_flat_case'])
                else:
                    dns = textwrap.dedent(
                        """

                        %sTODO(%s): Edit this file to reflect the changes needed for this variant.%s

                        """ % (comment_start, DNS, comment_end))

                    # Special case: HLCPP uses flat_case in the path to fidl.h.
                    contents = contents.replace(
                        "%s/%s/cpp/fidl.h" %
                        (subs['series_snake_case'], "baseline"),
                        "%s/%s/cpp/fidl.h" %
                        (subs['series_snake_case'], subs['variant_flat_case']))

                    contents = contents.replace(
                        "%s/%s" % (subs['series_snake_case'], "baseline"),
                        "%s/%s" %
                        (subs['series_snake_case'], subs['variant_snake_case']))
                    contents = contents.replace(
                        "baseline", subs['variant_flat_case'])

                # Do the actual file writes, and update the dns count so the user is aware that they
                # need to make further edits in this file.
                os.makedirs(os.path.dirname(out_path), exist_ok=True)
                dns_counts[str(
                    out_path)] = get_dns_count(contents) + (1 if dns else 0)
                with open(out_path, "wt") as f:
                    f.write(contents + dns)

    return dns_counts


def maybe_implement_test(series, variant, subs, fresh):
    """Implement the test implementation, and add a TODO to client.cml, if they do not yet exist.
    """
    dns_counts = {}

    # Ensure that the to-be-replaced TODO.md still exists.
    try:
        validate_todo_md_still_exists(series, variant, "test")
    except StepError:
        return dns_counts

    variant_code_root_path = EXAMPLE_CODE_BASE_DIR / series / variant
    todo_md_file_path = variant_code_root_path / "test" / "TODO.md"
    client_cml_path = variant_code_root_path / "meta/client.cml"

    # Ensure that the BUILD.gn for this variant still exists.
    variant_root_gn_file_path = variant_code_root_path / "BUILD.gn"
    if not os.path.exists(variant_root_gn_file_path):
        raise StepError(
            "Cannot scaffold an implementation for '%s/%s' because variant's BUILD.gn is missing"
            % (series, variant))

    # Validate that the client.cml file is where we expect it to be.
    if not os.path.exists(client_cml_path):
        raise StepError(
            "Cannot scaffold an implementation for '%s/%s' because the client.cml is missing"
            % (series, variant))

    # Update the client.cml file with a TODO telling the user to add some structured config.
    with open(client_cml_path, "r") as f:
        content = f.read()
        dns_count = get_dns_count(content)
        dns_counts[client_cml_path] = dns_count + 1
        with open(client_cml_path, "wt") as f:
            dns = textwrap.dedent(
                """
            // TODO(%s): Expand the structured config as necessary to set up this variant.
            """ % DNS)
            f.write(content + dns)

    # Update the variant BUILD.gn file with a TODO telling the user to add structured config
    # defaults to `client_config_values`.
    with open(variant_root_gn_file_path, "r") as f:
        content = f.read()
        dns_count = get_dns_count(content)
        dns_counts[variant_root_gn_file_path] = dns_count + 1
        with open(variant_root_gn_file_path, "wt") as f:
            dns = textwrap.dedent(
                """
            # TODO(%s): Add a `values` field to `client_config_values` after editing client.cml.
            """ % DNS)
            f.write(content + dns)

    # Remove the TODO.md file, then generate the templates in its place.
    os.remove(todo_md_file_path)
    binding_templates_dir = TEMPLATES_DIR / "implement_test"
    for path, count in apply_subs("test", subs, binding_templates_dir,
                                  variant_code_root_path).items():
        dns_counts[path] = count

    return dns_counts


def implement(name, binding, protocol, series, fresh):
    """Implement the canonical example in a single binding language.
    """
    variant = BASELINE
    if series:
        variant = name
    else:
        series = name
        fresh = True

    tutorial_md_file_path = EXAMPLE_DOCS_BASE_DIR / series / (
        "_%s_tutorial.md" % variant)
    variant_code_root_path = EXAMPLE_CODE_BASE_DIR / series / variant
    todo_md_file_path = variant_code_root_path / binding / "TODO.md"
    variant_root_gn_file_path = variant_code_root_path / "BUILD.gn"

    # Validate the presence of the tutorial markdown file.
    if not (os.path.exists(tutorial_md_file_path) and
            os.path.exists(variant_code_root_path)):
        raise StepError(
            "Cannot scaffold %s binding for '%s/%s' because this variant has not yet been created"
            % (binding, series, variant))

    # Ensure that the variant's BUILD.gn file exists.
    if not os.path.exists(variant_root_gn_file_path):
        raise StepError(
            "Cannot scaffold %s binding for '%s/%s' because root BUILD.gn file %s does not exist"
            % (binding, variant, variant_root_gn_file_path))

    # Build the subs, and ensure that the to-be-replaced TODO.md still exists.
    subs = build_subs(series, variant, protocol, None)
    validate_todo_md_still_exists(series, variant, binding)

    # If it doesn't exist yet, generate the test implementation as well.
    dns_counts = maybe_implement_test(series, variant, subs, fresh)

    # Load this file now, since it was just updated.
    variant_gn_dnrc_lines = validate_entry_does_not_already_exist(
        "%s:tests" % binding,
        {variant_root_gn_file_path: ''})[variant_root_gn_file_path]

    # Add an entry to the root BUILD.gn file for this variant.
    with open(variant_root_gn_file_path, "wt") as f:
        lines, start, end = variant_gn_dnrc_lines
        lines.insert(end, """    "%s:tests",\n""" % binding)
        f.write("".join(lines))

    # Update the tutorial markdown file to no longer point to the TODO.md file, and instead point it
    # at the actual client and server implementations.
    with open(tutorial_md_file_path, "r") as f:
        replaced_client_todo = f.read().replace(
            """%s/TODO.md" region_tag="todo" """ % binding,
            """%s/client/%s" highlight="TODO(%s)" """ %
            (binding, BINDINGS[binding], DNS), 1)
        replaced_both_todos = replaced_client_todo.replace(
            """%s/TODO.md" region_tag="todo" """ % binding,
            """%s/server/%s" highlight="TODO(%s)" """ %
            (binding, BINDINGS[binding], DNS), 1)
        dns_counts[tutorial_md_file_path] = 2
        with open(tutorial_md_file_path, "wt") as f:
            f.write(replaced_both_todos)

    # Remove the TODO.md file.
    os.remove(todo_md_file_path)

    # If the user request a "fresh" instance, generate the templates. Otherwise, copy them over from
    # the baseline case.
    generated = {}
    if fresh:
        binding_templates_dir = TEMPLATES_DIR / ("implement_%s" % binding)
        generated = apply_subs(
            binding, subs, binding_templates_dir, variant_code_root_path)
    else:
        generated = copy_baseline_implementation(series, variant, binding, subs)

    # Update the DNS counts to reflect the newly added impl files and report to the user.
    for path, count in generated.items():
        dns_counts[path] = count

    report_success(dns_counts)


def report_success(dns_counts):
    """Print some useful output to the user describing what they need to do next.
    """
    if len(dns_counts):
        print(
            textwrap.dedent(
                """
            Success!

            Several generated files contain comments of the form "TODO(%s)".
            Please replace them with the appropriate content, as specified by in their descriptions:
        """ % DNS))
        for path, count in dns_counts.items():
            if count > 0:
                print("    * %d occurrences in %s" % (count, path))
        print()


def pascal_case(arg):
    """Check that command-line argument strings are PascalCase.
    """
    if not is_pascal_case(arg):
        raise argparse.ArgumentTypeError("'%s' must be PascalCase" % arg)
    return arg


def snake_case(arg):
    """Check that command-line argument strings are snake_case.
    """
    if not is_snake_case(arg):
        raise argparse.ArgumentTypeError("'%s' must be snake_case" % arg)
    return arg


def snake_case_list(arg):
    """Check that command-line argument lists are all snake_case strings.
    """
    as_list = []
    for item in arg.split(","):
        item = item.strip()
        if not is_snake_case(item):
            raise argparse.ArgumentTypeError(
                "'%s' must be a list of snake_case strings" % arg)
        as_list.append(item)
    return as_list


def unsigned_int(arg):
    """Argument parsing helper to validate unsigned integers.
    """
    as_int = int(arg)
    if as_int <= 0:
        raise argparse.ArgumentTypeError(
            "'%s' must be an unsigned integer" % as_int)
    return as_int


def main(args):
    """Scaffolding scripts for the FIDL canonical examples effort.
    """
    if args.command_used == "create":
        return create(args.name, args.protocol, args.bug, args.series)
    if args.command_used == "document":
        return document(args.name, args.concepts[0])
    if args.command_used == "implement":
        return implement(
            args.name, args.binding, args.protocol, args.series, args.fresh)
    raise argparse.ArgumentTypeError("Unknown command '%s'" % args.command_used)


if __name__ == '__main__':
    details = {
        'create':
            """Create a new canonical example variant, with `TODO.md` placeholders files in place of
            future implementations.""",
        'document':
            """Document a canonical example variant, which enables writing all of the tutorial text
            that accompanies the variant.""",
        'implement':
            """Implement a canonical example variant in a single binding language. If this is the
            first implementation of the canonical example variant, test scripts will need to be
            filled in as well.""",
    }
    helps = {
        'binding':
            """The language binding being implemented.""",
        'bug':
            """The bug associated with this canonical example entry.""",
        'concepts':
            """The concepts associated with this variant - each will receive its own widget.""",
        'fresh':
            """When creating a new variant implementation, enable this flag to create a blank
            scaffold, rather than copying the baseline implementation.""",
        'from':
            """The name of the canonical example series that this example is an extension of. If
            this argument is omitted, the --baseline flag must be specified instead to indicate that
            we are creating the baseline case of a brand new canonical example series of the
            specified name.""",
        'baseline':
            """If this is a new canonical example series, this flag needs to be included to indicate
            this fact.""",
        'name':
            """The name of the canonical example variant being affected by this command.""",
        'protocol':
            """The @discoverable protocol that serves as the first contact point for the client and
            server in this example.""",
    }
    args = argparse.ArgumentParser(
        description="Create or modify FIDL canonical example.")
    commands = args.add_subparsers(
        dest="command_used",
        help="Commands (specify command followed by --help for details)",
    )

    # Specify the create command, used to create a new canonical example series, or a new variant in
    # an already existing one.
    create_cmd = commands.add_parser("create", help=details["create"])
    create_cmd.add_argument(
        "name", metavar="name", type=snake_case, help=helps['name'])
    create_cmd.add_argument(
        "--protocol", type=pascal_case, required=True, help=helps['protocol'])
    create_cmd.add_argument(
        "--bug", type=unsigned_int, required=True, help=helps['bug'])

    create_cmd_baseline_or_extend = create_cmd.add_mutually_exclusive_group(
        required=True)
    create_cmd_baseline_or_extend.add_argument(
        "--from", dest="series", type=snake_case, help=helps['from'])
    create_cmd_baseline_or_extend.add_argument(
        "--baseline", action='store_true', help=helps['baseline'])
    create_cmd_baseline_or_extend.set_defaults(baseline=True)

    # Specify the document command.
    document_cmd = commands.add_parser("document", help=details["document"])
    document_cmd.add_argument(
        "name", metavar="name", type=snake_case, help=helps['name'])
    document_cmd.add_argument(
        "--concepts", nargs='+', type=snake_case_list, help=helps['concepts'])

    # Specify the implement command.
    implement_cmd = commands.add_parser("implement", help=details["implement"])
    implement_cmd.add_argument(
        "name", metavar="name", type=snake_case, help=helps['name'])
    implement_cmd.add_argument(
        "--binding",
        type=snake_case,
        choices=BINDINGS.keys(),
        required=True,
        help=helps['binding'])
    implement_cmd.add_argument(
        "--protocol", type=pascal_case, required=True, help=helps['protocol'])
    implement_cmd.add_argument(
        "--fresh", action='store_true', help=helps['fresh'])
    implement_cmd.set_defaults(fresh=False)

    implement_cmd_baseline_or_extend = implement_cmd.add_mutually_exclusive_group(
        required=True)
    implement_cmd_baseline_or_extend.add_argument(
        "--from", dest="series", type=snake_case, help=helps['from'])
    implement_cmd_baseline_or_extend.add_argument(
        "--baseline", action='store_true', help=helps['baseline'])
    implement_cmd_baseline_or_extend.set_defaults(baseline=True)

    # Parse arguments.
    main(args.parse_args())
