import json
from typing import IO, Any

import click

import black


def generate_schema_from_click(
    cmd: click.Command,
) -> dict[str, Any]:
    result: dict[str, dict[str, Any]] = {}
    for param in cmd.params:
        if not isinstance(param, click.Option) or param.is_eager:
            continue

        assert param.name
        name = param.name.replace("_", "-")

        result[name] = {}

        match param.type:
            case click.types.IntParamType():
                result[name]["type"] = "integer"
            case click.types.StringParamType() | click.types.Path():
                result[name]["type"] = "string"
            case click.types.Choice(choices=choices):
                result[name]["enum"] = choices
            case click.types.BoolParamType():
                result[name]["type"] = "boolean"
            case _:
                msg = f"{param.type!r} not a known type for {param}"
                raise TypeError(msg)

        if param.multiple:
            result[name] = {"type": "array", "items": result[name]}

        result[name]["description"] = param.help

        if param.default is not None and not param.multiple:
            result[name]["default"] = param.default

    return result


@click.command(context_settings={"help_option_names": ["-h", "--help"]})
@click.option("--schemastore", is_flag=True, help="SchemaStore format")
@click.option("--outfile", type=click.File(mode="w"), help="Write to file")
def main(schemastore: bool, outfile: IO[str]) -> None:
    properties = generate_schema_from_click(black.main)
    del properties["line-ranges"]

    schema: dict[str, Any] = {
        "$schema": "http://json-schema.org/draft-07/schema#",
        "$id": (
            "https://github.com/psf/black/blob/main/src/black/resources/black.schema.json"
        ),
        "$comment": "tool.black table in pyproject.toml",
        "type": "object",
        "additionalProperties": False,
        "properties": properties,
    }

    if schemastore:
        schema["$id"] = "https://json.schemastore.org/partial-black.json"
        # The precise list of unstable features may change frequently, so don't
        # bother putting it in SchemaStore
        schema["properties"]["enable-unstable-feature"]["items"] = {"type": "string"}

    print(json.dumps(schema, indent=2), file=outfile)


if __name__ == "__main__":
    main()
