"""
koci Validate Controller

Validates koci.yml pipeline files.
"""

import os
from cement import Controller, ex

from ..core import parse_pipeline, ParserError, ValidationError
from ..output import OutputFormatter, Verbosity


class Validate(Controller):
    """Controller for the 'validate' command."""

    class Meta:
        label = 'validate'
        stacked_on = 'base'
        stacked_type = 'nested'
        description = 'Validate a koci pipeline file'
        help = 'Validate pipeline syntax and semantics'

        arguments = [
            (['-f', '--file'],
             {'help': 'Path to koci.yml file',
              'action': 'store',
              'dest': 'file',
              'default': None}),

            (['--strict'],
             {'help': 'Enable strict validation',
              'action': 'store_true',
              'dest': 'strict',
              'default': False}),

            (['--show-schema'],
             {'help': 'Show the JSON schema',
              'action': 'store_true',
              'dest': 'show_schema',
              'default': False}),
        ]

    @ex(help='Validate pipeline file')
    def _default(self):
        """Validate the pipeline file."""
        formatter = OutputFormatter(verbosity=Verbosity.NORMAL)

        if self.app.pargs.show_schema:
            self._show_schema()
            return

        # Find and parse pipeline
        workspace = os.getcwd()

        try:
            pipeline = parse_pipeline(
                filepath=self.app.pargs.file,
                directory=workspace,
            )

            # Additional strict validations
            if self.app.pargs.strict:
                self._strict_validate(pipeline, formatter)

            formatter.success(f"Pipeline '{pipeline.name}' is valid!")
            formatter.print(f"  Stages: {len(pipeline.stages)}")
            formatter.print(f"  Jobs: {len(pipeline.get_all_jobs())}")

            # Show structure
            formatter.print("\nPipeline structure:")
            formatter.print_pipeline_graph(pipeline)

        except ParserError as e:
            formatter.error(f"Parse error: {e}")
            self.app.exit_code = 1

        except ValidationError as e:
            formatter.error(f"Validation error: {e}")
            self.app.exit_code = 1

    def _strict_validate(self, pipeline, formatter):
        """Perform strict validation checks."""
        warnings = []

        # Check for missing images
        for job in pipeline.get_all_jobs():
            if job.image == 'alpine:latest':
                warnings.append(
                    f"Job '{job.name}' uses default image. Consider specifying an explicit image."
                )

        # Check for jobs without steps
        for job in pipeline.get_all_jobs():
            if not job.steps:
                warnings.append(f"Job '{job.name}' has no steps defined.")

        # Check for potential issues with needs
        for job in pipeline.get_all_jobs():
            if job.needs:
                for needed in job.needs:
                    needed_job = pipeline.get_job(needed)
                    if needed_job and not needed_job.artifacts:
                        warnings.append(
                            f"Job '{job.name}' needs '{needed}' but '{needed}' "
                            f"doesn't produce artifacts."
                        )

        # Print warnings
        for warning in warnings:
            formatter.warning(warning)

    def _show_schema(self):
        """Show the JSON schema."""
        import json
        from ..core.schema import KOCI_SCHEMA

        print(json.dumps(KOCI_SCHEMA, indent=2))
