"""
koci YAML Schema Definition

JSON Schema for validating koci.yml pipeline files.
"""

KOCI_SCHEMA = {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "koci Pipeline Configuration",
    "description": "Schema for koci.yml CI/CD pipeline definition files",
    "type": "object",
    "required": ["stages", "jobs"],
    "properties": {
        "version": {
            "type": "string",
            "description": "Schema version",
            "default": "1"
        },
        "name": {
            "type": "string",
            "description": "Pipeline name"
        },
        "stages": {
            "type": "array",
            "description": "Ordered list of stage names",
            "items": {"type": "string"},
            "minItems": 1
        },
        "env": {
            "type": "object",
            "description": "Global environment variables",
            "additionalProperties": {"type": "string"}
        },
        "defaults": {
            "type": "object",
            "description": "Default values for jobs",
            "properties": {
                "image": {"type": "string"},
                "working_directory": {"type": "string"},
                "timeout_minutes": {"type": "integer", "minimum": 1}
            }
        },
        "services": {
            "type": "object",
            "description": "Services per stage",
            "additionalProperties": {
                "type": "array",
                "items": {"$ref": "#/definitions/service"}
            }
        },
        "jobs": {
            "type": "object",
            "description": "Job definitions",
            "additionalProperties": {"$ref": "#/definitions/job"}
        },
        "on": {
            "type": "object",
            "description": "Trigger configuration (for export)",
            "properties": {
                "push": {
                    "oneOf": [
                        {"type": "null"},
                        {
                            "type": "object",
                            "properties": {
                                "branches": {
                                    "type": "array",
                                    "items": {"type": "string"}
                                },
                                "tags": {
                                    "type": "array",
                                    "items": {"type": "string"}
                                }
                            }
                        }
                    ]
                },
                "pull_request": {
                    "oneOf": [
                        {"type": "null"},
                        {
                            "type": "object",
                            "properties": {
                                "branches": {
                                    "type": "array",
                                    "items": {"type": "string"}
                                }
                            }
                        }
                    ]
                },
                "schedule": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "cron": {"type": "string"}
                        }
                    }
                },
                "workflow_dispatch": {"type": ["object", "null"]}
            }
        }
    },
    "definitions": {
        "step": {
            "type": "object",
            "oneOf": [
                {
                    "required": ["run"],
                    "properties": {
                        "name": {"type": "string"},
                        "run": {"type": "string"},
                        "working_directory": {"type": "string"},
                        "env": {
                            "type": "object",
                            "additionalProperties": {"type": "string"}
                        },
                        "shell": {
                            "type": "string",
                            "enum": ["bash", "sh", "python", "pwsh", "cmd"]
                        },
                        "continue_on_error": {"type": "boolean", "default": False},
                        "timeout_minutes": {"type": "integer", "minimum": 1}
                    }
                }
            ]
        },
        "artifact": {
            "type": "object",
            "properties": {
                "paths": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Paths to upload as artifacts"
                },
                "consume": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Job names to download artifacts from"
                },
                "name": {
                    "type": "string",
                    "description": "Custom artifact name"
                },
                "retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90,
                    "default": 7
                }
            }
        },
        "service": {
            "type": "object",
            "required": ["image"],
            "properties": {
                "image": {"type": "string"},
                "name": {"type": "string"},
                "env": {
                    "type": "object",
                    "additionalProperties": {"type": "string"}
                },
                "ports": {
                    "type": "array",
                    "items": {"type": "string"}
                },
                "volumes": {
                    "type": "array",
                    "items": {"type": "string"}
                },
                "options": {
                    "type": "array",
                    "items": {"type": "string"}
                },
                "healthcheck": {
                    "type": "object",
                    "properties": {
                        "test": {
                            "oneOf": [
                                {"type": "string"},
                                {"type": "array", "items": {"type": "string"}}
                            ]
                        },
                        "interval": {"type": "string"},
                        "timeout": {"type": "string"},
                        "retries": {"type": "integer"}
                    }
                }
            }
        },
        "matrix": {
            "type": "object",
            "additionalProperties": {
                "type": "array",
                "items": {
                    "oneOf": [
                        {"type": "string"},
                        {"type": "number"},
                        {"type": "boolean"}
                    ]
                }
            }
        },
        "reports": {
            "type": "object",
            "description": "Test report configuration",
            "properties": {
                "junit": {
                    "type": "string",
                    "description": "Path/glob pattern to JUnit XML report file(s)"
                },
                "coverage": {
                    "oneOf": [
                        {"type": "string"},
                        {
                            "type": "object",
                            "properties": {
                                "path": {
                                    "type": "string",
                                    "description": "Path to coverage report file"
                                },
                                "format": {
                                    "type": "string",
                                    "enum": ["cobertura", "lcov", "auto"],
                                    "default": "auto",
                                    "description": "Coverage report format"
                                },
                                "threshold": {
                                    "type": "number",
                                    "minimum": 0,
                                    "maximum": 100,
                                    "description": "Fail if coverage below this percentage"
                                }
                            },
                            "required": ["path"]
                        }
                    ]
                }
            }
        },
        "job": {
            "type": "object",
            "required": ["stage", "steps"],
            "properties": {
                "stage": {"type": "string"},
                "image": {"type": "string"},
                "steps": {
                    "type": "array",
                    "items": {"$ref": "#/definitions/step"},
                    "minItems": 1
                },
                "needs": {
                    "type": "array",
                    "items": {"type": "string"}
                },
                "artifacts": {"$ref": "#/definitions/artifact"},
                "reports": {"$ref": "#/definitions/reports"},
                "matrix": {"$ref": "#/definitions/matrix"},
                "when": {
                    "type": "string",
                    "description": "Simple condition expression"
                },
                "if": {
                    "type": "string",
                    "description": "Complex condition expression"
                },
                "env": {
                    "type": "object",
                    "additionalProperties": {"type": "string"}
                },
                "working_directory": {"type": "string", "default": "/workspace"},
                "timeout_minutes": {"type": "integer", "minimum": 1, "default": 60},
                "continue_on_error": {"type": "boolean", "default": False},
                "retry": {"type": "integer", "minimum": 0, "maximum": 5, "default": 0},
                "parallel": {
                    "type": "boolean",
                    "default": False,
                    "description": "Run in parallel with other parallel jobs in the same stage"
                }
            }
        }
    }
}


# Example koci.yml for reference
EXAMPLE_PIPELINE = """
version: "1"
name: my-app-pipeline

stages:
  - build
  - test
  - deploy

env:
  NODE_ENV: production
  CI: "true"

defaults:
  image: node:20-alpine
  working_directory: /workspace

services:
  test:
    - image: postgres:15
      env:
        POSTGRES_USER: test
        POSTGRES_PASSWORD: test
        POSTGRES_DB: testdb
      ports:
        - "5432:5432"
    - image: redis:7
      ports:
        - "6379:6379"

jobs:
  install:
    stage: build
    steps:
      - name: Install dependencies
        run: npm ci
    artifacts:
      paths:
        - node_modules/

  lint:
    stage: build
    needs: [install]
    steps:
      - run: npm run lint
    artifacts:
      consume: [install]

  compile:
    stage: build
    needs: [install]
    steps:
      - name: Build application
        run: npm run build
    artifacts:
      consume: [install]
      paths:
        - dist/

  unit-tests:
    stage: test
    needs: [compile]
    image: node:20
    matrix:
      node: ["18", "20", "22"]
    steps:
      - name: Run unit tests
        run: npm test
        env:
          DATABASE_URL: postgres://test:test@localhost:5432/testdb
          REDIS_URL: redis://localhost:6379
    artifacts:
      consume: [install, compile]

  integration-tests:
    stage: test
    needs: [compile]
    steps:
      - run: npm run test:integration
    artifacts:
      consume: [install, compile]

  deploy-staging:
    stage: deploy
    needs: [unit-tests, integration-tests]
    when: branch == 'develop'
    steps:
      - name: Deploy to staging
        run: ./scripts/deploy.sh staging
    artifacts:
      consume: [compile]

  deploy-production:
    stage: deploy
    needs: [unit-tests, integration-tests]
    when: branch == 'main'
    if: ${{ success() && github.event_name == 'push' }}
    steps:
      - name: Deploy to production
        run: ./scripts/deploy.sh production
    artifacts:
      consume: [compile]

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
"""
