__author__ = "Vanessa Sochat"
__copyright__ = "Copyright 2022, Vanessa Sochat"
__license__ = "MPL 2.0"

from pygments.styles import get_all_styles

# Derived from https://github.com/softprops/github-actions-schemas/blob/master/workflow.json

schema_url = "http://json-schema.org/draft-07/schema"

workflow_schema = {
    "title": "Github workflow file - https://help.github.com/en/articles/workflow-syntax-for-github-actions",
    "$schema": schema_url,
    "type": "object",
    "required": ["on"],
    "properties": {
        "name": {
            "type": "string",
            "description": "The name of your workflow. GitHub displays the names of your workflows on your repository's actions page. If you omit this field, GitHub sets the name to the workflow's filename.",
        },
        "on": {
            "description": "The name of the GitHub event that triggers the workflow",
            "oneOf": [
                {"$ref": "#/definitions/webhook_event"},
                {"type": "array", "items": {"$ref": "#/definitions/webhook_event"}},
                {
                    "type": "object",
                    "addditionalProperties": {
                        "type": "object",
                        "properties": {
                            "branches": {
                                "description": "list of branches",
                                "type": "array",
                                "items": {"type": "string"},
                            },
                            "tags": {"type": "array", "items": {"type": "string"}},
                            "paths": {"type": "array", "items": {"type": "string"}},
                        },
                    },
                },
                {
                    "type": "object",
                    "properties": {
                        "schedule": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {"cron": {"type": "string"}},
                            },
                        }
                    },
                },
            ],
        },
        "jobs": {
            "description": "A workflow run is made up of one or more jobs. Jobs run in parallel by default. To run jobs sequentially, you can define dependencies on other jobs using the jobs.<job_id>.needs keyword.",
            "type": "object",
            "additionalProperties": {
                "type": "object",
                "description": "Each job must have an id to associate with the job. The key job_id is a string and its value is a map of the job's configuration data. You must replace <job_id> with a string that is unique to the jobs object. The <job_id> must start with a letter or _ and contain only alphanumeric characters, -, or _.",
                "required": ["runs-on"],
                "properties": {
                    "name": {
                        "description": "The name of the job displayed on GitHub.",
                        "type": "string",
                    },
                    "needs": {
                        "description": "Identifies any jobs that must complete successfully before this job will run. It can be a string or array of strings. If a job fails, all jobs that need it will also fail unless the jobs use a conditional statement that causes the job to continue.",
                        "oneOf": [
                            {"type": "string"},
                            {"type": "array", "items": {"type": "string"}},
                        ],
                    },
                    "runs-on": {
                        "description": "The type of virtual host machine to run the job on. Each job runs with a fresh instance of the virtual environment specified in by runs-on",
                        "type": "string",
                        "default": "ubuntu-latest",
                        "enum": [
                            "ubuntu-latest",
                            "ubuntu-18.04",
                            "ubuntu-16.04",
                            "windows-latest",
                            "windows-2019",
                            "windows-2016",
                            "macOS-latest",
                            "macOS-10.14",
                        ],
                    },
                    "steps": {
                        "description": "A job contains a sequence of tasks called steps. Steps can run commands, run setup tasks, or run an action in your repository, a public repository, or an action published in a Docker registry. Not all steps run actions, but all actions are run as a step. Each step runs in its own process in the virtual environment and has access to the workspace and filesystem. Because steps are run in their own process, changes to environment variables are not preserved between steps. GitHub provides built-in steps to set up and complete a job.",
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "description": "A name for your step to display on GitHub.",
                                    "type": "string",
                                },
                                "uses": {
                                    "description": "Selects an action to run as part of a step in your job. An action is a reusable unit of code. You can use an action defined in the same repository as the workflow, a public repository, or in a published Docker container image.",
                                    "type": "string",
                                },
                                "with": {
                                    "type": "object",
                                    "description": "A map of the input parameters defined by the action. Each input parameter is a key/value pair. Input parameters are set as environment variables. The variable is prefixed with INPUT_ and converted to upper case.",
                                    "addtionalProperties": {"type": "string"},
                                },
                                "env": {
                                    "type": "object",
                                    "description": "Sets environment variables for steps to use in the virtual environment. Public actions may specify expected environment variables in the README file. If you are setting a secret in an environment variable, you must set secrets using the secrets context.",
                                    "addtionalProperties": {"type": "string"},
                                },
                                "if": {
                                    "description": "Identifies any steps that must complete successfully before this step will run. It can be a string or an array of strings. If a step fails, all steps that need it will also fail unless the steps use a conditional statement that causes the step to continue.",
                                    "type": "string",
                                },
                                "run": {
                                    "description": "Runs command line programs using the operating system's shell. If you do not provide a name, the step name will default to the run command. Commands run using non-login shells by default.",
                                    "type": "string",
                                },
                                "working-directory": {
                                    "description": "The default directory that the action uses in a job's workspace.",
                                    "type": "string",
                                },
                                "continue-on-error": {
                                    "description": "Prevents a job from failing when a step fails. Set to true to allow a job to pass when this step fails.",
                                    "type": "boolean",
                                },
                                "timeout-minutes": {
                                    "description": "The maximum number of minutes to let a workflow run before GitHub automatically cancels it.",
                                    "type": "number",
                                },
                            },
                        },
                    },
                },
            },
        },
    },
    "definitions": {"webhook_event": {"enum": ["push"]}},
}

keyvals = {
    "type": "object",
    "patternProperties": {
        "\\w[\\w-]*": {"type": "string"},
    },
}

# We allow updaters to have any dict structure - they are responsible for validating
updaters_schema = {
    "type": "object",
    "patternProperties": {
        "\\w[\\w-]*": {"type": "object"},
    },
}

# Currently all of these are required
settingsProperties = {
    "github_api": {"type": "string"},
    "config_editor": {"type": "string"},
    "updaters": updaters_schema,
    "code_theme": {"type": "string", "choices": list(get_all_styles())},
}

settings = {
    "$schema": schema_url,
    "title": "Settings Schema",
    "type": "object",
    "required": [
        "github_api",
        "config_editor",
        "code_theme",
        "updaters",
    ],
    "properties": settingsProperties,
    "additionalProperties": False,
}
