{
    "$schema": "http://json-schema.org/schema#",
    "type": "object",
    "properties": {
        "type": {
            "type": "string",
            "description": "The service type (should always be 'codedeploy')",
            "pattern": "codedeploy",
            "errorMessage": "Must equal 'codedeploy'"
        },
        "path_to_code": {
            "type": "string",
            "description": "The location of the directory you want to upload to CodeDeploy",
            "errorMessage": "Must be a string"
        },
        "os": {
            "type": "string",
            "description": "The type of OS to use with CodeDeploy",
            "pattern": "^linux$",
            "errorMessage": "Currently may only be 'linux'"
        },
        "instance_type": {
            "type": "string",
            "description": "The EC2 instance type on which your application will run",
            "errorMessage": "Must be a string"            
        },
        "key_name": {
            "type": "string",
            "description": "The name of the EC2 keypair to use for SSH access to the instances",
            "errorMessage": "Must be a string"
        },
        "auto_scaling": {
            "type": "object",
            "properties": {
                "min_instances": {
                    "type": "number",
                    "minimum": 1,
                    "errorMessage": "Must be a number >= 1"
                },
                "max_instances": {
                    "type": "number",
                    "minimum": 1,
                    "errorMessage": "Must be a number >= 1"
                },
                "scaling_policies": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": "string"
                            },
                            "adjustment": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "errorMessage": "Must be a string"
                                    },
                                    "value": {
                                        "type": "number",
                                        "errorMessage": "Must be a number"
                                    },
                                    "cooldown": {
                                        "type": "number",
                                        "errorMessage": "Must be a number"
                                    }
                                },
                                "additionalProperties": false,
                                "required": [
                                    "value"
                                ],
                                "errorMessage": {
                                    "additionalProperties": "Invalid/unknown property specified",
                                    "required": {
                                        "value": "The 'value' field is required"
                                    }
                                }
                            },
                            "alarm": {
                                "type": "object",
                                "properties": {
                                    "namespace": {
                                        "type": "string",
                                        "errorMessage": "Must be a string"
                                    },
                                    "dimensions": {
                                        "type": "object",
                                        "errorMessage": "Must be a set of key/value pairs"
                                    },
                                    "metric_name": {
                                        "type": "string",
                                        "errorMessage": "Must be a string"
                                    },
                                    "statistic": {
                                        "type": "string",
                                        "errorMessage": "Must be a string"
                                    },
                                    "comparison_operator": {
                                        "type": "string",
                                        "errorMessage": "Must be a string"
                                    },
                                    "threshold": {
                                        "type": "number",
                                        "errorMessage": "Must be a number"
                                    },
                                    "period": {
                                        "type": "number",
                                        "errorMessage": "Must be a number"
                                    },
                                    "evaluation_periods": {
                                        "type": "number",
                                        "errorMessage": "Must be a number"
                                    }
                                },
                                "additionalProperties": false,
                                "required": [
                                    "metric_name",
                                    "threshold"
                                ],
                                "errorMessage": {
                                    "additionalProperties": "Invalid/unknown property specified",
                                    "required": {
                                        "metric_name": "The 'metric_name' field is required",
                                        "threshold": "The 'threshold' field is required"
                                    }
                                }
                            }
                        },
                        "additionalProperties": false,
                        "required": [
                            "type",
                            "adjustment",
                            "alarm"
                        ],
                        "errorMessage": {
                            "additionalProperties": "Invalid/unknown property specified",
                            "required": {
                                "type": "The 'type' field is required",
                                "adjustment": "The 'adjustment' field is required",
                                "alarm": "The 'alarm' field is required"
                            }
                        }
                    }
                }
            },
            "required": [
                "min_instances",
                "max_instances"
            ],
            "additionalProperties": false,
            "errorMessage": {
                "additionalProperties": "Invalid/unknown property specified",
                "required": {
                    "min_instances": "The 'min_instances' field is required",
                    "max_instances": "The 'max_instances' field is required"
                }
            }
        },
        "routing": {
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "description": "Whether to use HTTP or HTTPS for the routing listener",
                    "pattern": "^(http|https)$",
                    "errorMessage": "Must be one of the values: http, https"
                },
                "https_certificate": {
                    "type": "string",
                    "description": "The certificate ID from AWS Certificate Manager",
                    "errorMessage": "Must be a string"
                },
                "dns_names": {
                    "type": "array",
                    "items": {
                        "type": "string",
                        "errorMessage": "The items in the 'dns_names' field must be a string"
                    },
                    "errorMessage": "Must be an array of strings"
                }
            },
            "additionalProperties": false,
            "required": [
                "type"
            ],
            "errorMessage": {
                "type": "The 'routing' section should be an object containing at least the 'type' field",
                "additionalProperties": "Invalid/unknown property specified in the 'routing' section",
                "required": {
                    "type": "Must be specified in the 'routing' section"
                }
            }
        },
        "environment_variables": {
            "type": "object",
            "description": "Any user-specified environment variables to inject in the application",
            "patternProperties": {
                "^.*$": {
                    "anyOf": [
                        {"type": "string"},
                        {"type": "number"},
                        {"type": "boolean"}
                    ]
                }
            },
            "errorMessage": "Must contain 1 or more simple key/value pairs where the values are strings or numbers",
            "additionalProperties": false
        },
        "tags": {
            "type": "object",
            "description": "An arbitrary list of key/value pairs to be added as tags to the service",
            "patternProperties": {
                "^.*$": {
                    "anyOf": [
                        {"type": "string"},
                        {"type": "number"}
                    ]
                }
            },
            "errorMessage": "Must contain 1 or more simple key/value pairs where the values are strings or numbers",
            "additionalProperties": false
        },
        "dependencies": {
            "type": "array",
            "items": {
                "type": "string",
                "errorMessage": "Each item must be a string"
            },
            "errorMessage": "Must be an array of strings"
        }
    },
    "required": [
        "type",
        "path_to_code",
        "os"
    ],
    "additionalProperties": false,
    "errorMessage": {
        "additionalProperties": "Invalid/unknown property specified",
        "required": {
            "type": "The 'type' property is required",
            "path_to_code": "The 'path_to_code' field is required",
            "os": "The 'os' field is required"
        }
    }
}