package devopsmodules

import (
	"rubric/utils"
)

var TerraformModule = Module{
	Key:         "terraform",
	Aliases:     []string{"tf", "iac", "infra"},
	Title:       "Terraform — инфраструктура как код",
	Description: "HCL, провайдеры, ресурсы, state, модули, workspace",
	Run:         showTerraform,
}

func showTerraform() {
	utils.Header("DevOps — Terraform")

	utils.Section("Основы и установка")
	utils.Code(`Terraform — декларативный IaC инструмент от HashiCorp.
Описываешь желаемое состояние → Terraform приводит инфраструктуру к нему.

# Установка:
# https://developer.hashicorp.com/terraform/install
# Linux (apt):
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor \
  -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=...] https://apt.releases.hashicorp.com $(lsb_release -cs) main" \
  | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform

terraform version
terraform -install-autocomplete`)

	utils.Section("Жизненный цикл")
	utils.Code(`terraform init      # скачать провайдеры, инициализировать backend
terraform validate  # проверить синтаксис
terraform fmt       # форматировать код
terraform plan      # показать что изменится
terraform apply     # применить изменения
terraform destroy   # удалить всю инфраструктуру

terraform plan -out=plan.tfplan    # сохранить план
terraform apply plan.tfplan        # применить сохранённый план
terraform apply -auto-approve      # без подтверждения (CI/CD)
terraform apply -target=aws_instance.web  # только конкретный ресурс
terraform plan -var="region=eu-west-1"
terraform plan -var-file="prod.tfvars"`)

	utils.Section("Синтаксис HCL")
	utils.Code(`# main.tf — основная конфигурация:
terraform {
  required_version = ">= 1.7"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket  = "my-tf-state"
    key     = "prod/terraform.tfstate"
    region  = "eu-west-1"
    encrypt = true
  }
}

provider "aws" {
  region  = var.aws_region
  profile = "myprofile"
}`)

	utils.Code(`# variables.tf — входные переменные:
variable "aws_region" {
  description = "AWS регион"
  type        = string
  default     = "eu-west-1"
}

variable "instance_count" {
  type    = number
  default = 2
}

variable "allowed_cidrs" {
  type    = list(string)
  default = ["10.0.0.0/8"]
}

variable "tags" {
  type = map(string)
  default = {
    Environment = "production"
    Team        = "backend"
  }
}

variable "db_password" {
  type      = string
  sensitive = true   # не показывать в логах
}`)

	utils.Code(`# outputs.tf — выходные значения:
output "web_ip" {
  value       = aws_instance.web.public_ip
  description = "Публичный IP веб-сервера"
}

output "db_endpoint" {
  value     = aws_db_instance.main.endpoint
  sensitive = true
}`)

	utils.Code(`# Использование переменных:
resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
  count         = var.instance_count

  tags = merge(var.tags, {
    Name = "web-${count.index + 1}"
  })
}

# locals — локальные вычисляемые значения:
locals {
  name_prefix = "${var.project}-${var.environment}"
  common_tags = {
    Project     = var.project
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}`)

	utils.Section("Основные ресурсы (AWS)")
	utils.Code(`# Data sources — чтение существующих ресурсов:
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]   # Canonical
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"]
  }
}

data "aws_vpc" "default" {
  default = true
}

# EC2:
resource "aws_instance" "web" {
  ami                    = data.aws_ami.ubuntu.id
  instance_type          = "t3.micro"
  subnet_id              = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.web.id]
  key_name               = "mykey"
  user_data              = file("scripts/init.sh")

  root_block_device {
    volume_size = 20
    encrypted   = true
  }

  lifecycle {
    create_before_destroy = true
    ignore_changes        = [ami]
  }

  tags = local.common_tags
}

# Security Group:
resource "aws_security_group" "web" {
  name   = "${local.name_prefix}-web-sg"
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# S3 Bucket:
resource "aws_s3_bucket" "assets" {
  bucket = "${local.name_prefix}-assets"
}

resource "aws_s3_bucket_versioning" "assets" {
  bucket = aws_s3_bucket.assets.id
  versioning_configuration {
    status = "Enabled"
  }
}`)

	utils.Section("Модули (Modules)")
	utils.Code(`# Модуль — переиспользуемая конфигурация
# modules/ec2/main.tf, variables.tf, outputs.tf

# Использование модуля:
module "web_servers" {
  source = "./modules/ec2"
  # или из реестра:
  # source  = "terraform-aws-modules/ec2-instance/aws"
  # version = "~> 5.0"

  instance_count = 3
  instance_type  = "t3.small"
  vpc_id         = aws_vpc.main.id
  subnet_ids     = aws_subnet.public[*].id
  tags           = local.common_tags
}

output "web_ips" {
  value = module.web_servers.public_ips
}

# Популярные модули из реестра registry.terraform.io:
# terraform-aws-modules/vpc/aws
# terraform-aws-modules/eks/aws
# terraform-aws-modules/rds/aws`)

	utils.Section("State и Backend")
	utils.Code(`# State — файл состояния (terraform.tfstate)
# Хранит текущее состояние инфраструктуры.
# НЕ коммити в Git! Содержит секреты.

# Remote backend — общий state для команды:
# S3 + DynamoDB (для lock):
backend "s3" {
  bucket         = "my-tf-state"
  key            = "prod/terraform.tfstate"
  region         = "eu-west-1"
  encrypt        = true
  dynamodb_table = "tf-state-lock"   # блокировка
}

# Команды state:
terraform state list                       # список ресурсов в state
terraform state show aws_instance.web      # детали ресурса
terraform state mv aws_instance.old aws_instance.new  # переименовать
terraform state rm aws_instance.web        # убрать из state (не удалять)
terraform import aws_instance.web i-1234567890  # импортировать существующий

# Workspace — несколько окружений в одном конфиге:
terraform workspace list
terraform workspace new staging
terraform workspace select production
# В коде: terraform.workspace → "staging" / "production"`)

	utils.Section("Лучшие практики")
	utils.Code(`Структура проекта:
  infra/
  ├── modules/           # переиспользуемые модули
  │   ├── vpc/
  │   ├── eks/
  │   └── rds/
  ├── environments/
  │   ├── staging/
  │   │   ├── main.tf
  │   │   ├── variables.tf
  │   │   └── staging.tfvars
  │   └── production/
  │       ├── main.tf
  │       └── production.tfvars
  └── .terraform.lock.hcl   # версии провайдеров (коммитить!)

Правила:
- Всегда планируй перед apply: terraform plan
- Remote state с блокировкой для командной работы
- Раздели state по окружениям и компонентам
- Используй .terraform.lock.hcl в git
- sensitive = true для секретных переменных
- Используй terragrunt для DRY-конфигураций

Инструменты:
  tflint    — линтинг Terraform
  tfsec     — статический анализ безопасности
  checkov   — security и compliance checks
  terragrunt — обёртка для DRY-конфигурации
  atlantis   — автоматизация PR для Terraform`)

	utils.Footer()
}
