use colored::Colorize;
use lmrc_config_validator::LmrcConfig;
use std::fs;
use std::path::Path;

use crate::error::Result;

pub fn generate_gitlab_ci(project_path: &Path, config: &LmrcConfig) -> Result<()> {
    let gitlab_ci_content = generate_gitlab_ci_yaml(config);

    let ci_path = project_path.join(".gitlab-ci.yml");
    fs::write(&ci_path, gitlab_ci_content)?;

    println!("  {} .gitlab-ci.yml", "Created:".green());

    Ok(())
}

fn generate_gitlab_ci_yaml(config: &LmrcConfig) -> String {
    let app_build_jobs = config
        .apps
        .applications
        .iter()
        .map(|app| {
            format!(
                r#"
build:{}:
  stage: test
  image: rust:1.75
  script:
    - cd apps/{}
    - cargo build --release
    - cargo test
  artifacts:
    paths:
      - apps/{}/target/release/{}
    expire_in: 1 hour
  only:
    - main
    - merge_requests
"#,
                app.name, app.name, app.name, app.name
            )
        })
        .collect::<Vec<_>>()
        .join("\n");

    format!(
        r#"# LMRC Stack Pipeline Configuration
# Generated by lmrc-cli

variables:
  RUST_VERSION: "1.75"
  CARGO_HOME: $CI_PROJECT_DIR/.cargo

stages:
  - build-pipeline
  - test
  - provision
  - setup
  - deploy

# Cache for Rust builds
.rust_cache:
  cache:
    key: "${{CI_JOB_NAME}}"
    paths:
      - .cargo/
      - target/

# Build the pipeline binary first
build:pipeline:
  extends: .rust_cache
  stage: build-pipeline
  image: rust:$RUST_VERSION
  script:
    - cd infra/pipeline
    - cargo build --release
  artifacts:
    paths:
      - infra/pipeline/target/release/pipeline
    expire_in: 1 hour
  only:
    - main
    - merge_requests

# Build and test applications
{}

# Provision infrastructure
provision:
  stage: provision
  image: rust:$RUST_VERSION
  dependencies:
    - build:pipeline
  script:
    - ./infra/pipeline/target/release/pipeline provision
  only:
    - main
  when: manual

# Setup infrastructure (K8s, databases, etc.)
setup:
  stage: setup
  image: rust:$RUST_VERSION
  dependencies:
    - build:pipeline
  script:
    - ./infra/pipeline/target/release/pipeline setup
  only:
    - main
  needs:
    - provision

# Deploy applications
deploy:
  stage: deploy
  image: rust:$RUST_VERSION
  dependencies:
    - build:pipeline
  script:
    - ./infra/pipeline/target/release/pipeline deploy
  only:
    - main
  needs:
    - setup
"#,
        app_build_jobs
    )
}
