"""
Azure Pipelines template generator for Warden.

Generates Azure Pipelines YAML files for running Warden in CI/CD.
"""

from dataclasses import dataclass
from typing import Dict, List, Optional
from pathlib import Path


@dataclass
class AzurePipelinesConfig:
    """Configuration for Azure Pipelines."""

    pipeline_name: str = "Warden Analysis"
    trigger_branches: List[str] = None
    pool: str = "ubuntu-latest"
    python_version: str = "3.11"
    warden_version: Optional[str] = None
    fail_on_issues: bool = True
    publish_artifacts: bool = True
    frames: Optional[List[str]] = None

    def __post_init__(self):
        if self.trigger_branches is None:
            self.trigger_branches = ["main", "dev"]
        if self.frames is None:
            self.frames = ["security", "fuzz", "property"]


class AzurePipelinesTemplate:
    """Generates Azure Pipelines templates for Warden."""

    @staticmethod
    def generate(config: AzurePipelinesConfig) -> str:
        """
        Generate Azure Pipelines YAML content.

        Args:
            config: Configuration for the pipeline

        Returns:
            YAML content as string
        """
        warden_install = (
            f"pip install warden-core=={config.warden_version}"
            if config.warden_version
            else "pip install warden-core"
        )

        frames_arg = (
            " ".join(f"--frame {frame}" for frame in config.frames)
            if config.frames
            else ""
        )

        fail_arg = "--fail-on-issues" if config.fail_on_issues else ""

        trigger_section = AzurePipelinesTemplate._generate_triggers(
            config.trigger_branches
        )

        publish_section = (
            AzurePipelinesTemplate._generate_publish()
            if config.publish_artifacts
            else ""
        )

        template = f"""# Azure Pipelines for Warden Analysis
# Auto-generated by Warden Infrastructure Module

name: {config.pipeline_name}

{trigger_section}

pool:
  vmImage: '{config.pool}'

variables:
  pythonVersion: '{config.python_version}'

steps:
- task: UsePythonVersion@0
  displayName: 'Use Python $(pythonVersion)'
  inputs:
    versionSpec: '$(pythonVersion)'

- script: |
    python -m pip install --upgrade pip
    {warden_install}
  displayName: 'Install Warden'

- script: |
    warden analyze {frames_arg} {fail_arg} --ci --output $(Build.ArtifactStagingDirectory)/warden-report.json
  displayName: 'Run Warden Analysis'
  continueOnError: {str(not config.fail_on_issues).lower()}

{publish_section}

- task: PublishBuildArtifacts@1
  displayName: 'Publish Warden Report'
  condition: always()
  inputs:
    PathtoPublish: '$(Build.ArtifactStagingDirectory)'
    ArtifactName: 'warden-analysis'
    publishLocation: 'Container'
"""

        return template

    @staticmethod
    def _generate_triggers(branches: List[str]) -> str:
        """Generate trigger section."""
        if len(branches) == 1:
            return f"trigger:\n  - {branches[0]}"

        lines = ["trigger:"]
        for branch in branches:
            lines.append(f"  - {branch}")

        return "\n".join(lines)

    @staticmethod
    def _generate_publish() -> str:
        """Generate publish artifacts section."""
        return """- script: |
    echo "##vso[task.uploadsummary]$(Build.ArtifactStagingDirectory)/warden-report.json"
  displayName: 'Upload Summary'
  condition: always()
"""

    @staticmethod
    def save_to_file(config: AzurePipelinesConfig, output_path: Path) -> None:
        """
        Generate and save pipeline to file.

        Args:
            config: Pipeline configuration
            output_path: Path to save pipeline file
        """
        content = AzurePipelinesTemplate.generate(config)
        output_path.parent.mkdir(parents=True, exist_ok=True)
        output_path.write_text(content)

    @staticmethod
    def validate_pipeline(pipeline_path: Path) -> bool:
        """
        Validate Azure Pipelines file.

        Args:
            pipeline_path: Path to pipeline file

        Returns:
            True if valid, False otherwise
        """
        if not pipeline_path.exists():
            return False

        try:
            import yaml

            content = pipeline_path.read_text()
            data = yaml.safe_load(content)

            # Basic validation
            if not isinstance(data, dict):
                return False

            # Check for steps
            if "steps" not in data:
                return False

            if not isinstance(data["steps"], list):
                return False

            return True

        except Exception:
            return False
