#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Скрипт подстановки переменных окружения из .env/env.example в файл шаблона.

Автор: Сергей Антропов
Сайт: https://devops.org.ru

Использование:
  python3 app/scripts/substitute_env.py PATH_TO_ENV PATH_TO_COMPOSE_FILE

Логика:
- Читает пары KEY=VALUE из указанного env-файла (игнорирует комментарии и пустые строки)
- Не выполняет файл как shell (безопасно парсит)
- Заменяет плейсхолдеры вида ${KEY} в целевом файле
"""

from __future__ import annotations

import io
import os
import re
import sys
from typing import Dict


def parse_env_file(env_path: str) -> Dict[str, str]:
    """Простой парсер .env файла: KEY=VALUE, без исполнения shell."""
    variables: Dict[str, str] = {}
    with io.open(env_path, "r", encoding="utf-8") as fh:
        for raw in fh:
            line = raw.strip()
            if not line or line.startswith("#"):
                continue
            if "=" not in line:
                continue
            key, val = line.split("=", 1)
            key = key.strip()
            val = val.strip()
            # Снимаем внешние кавычки, если присутствуют
            if (val.startswith('"') and val.endswith('"')) or (
                val.startswith("'") and val.endswith("'")
            ):
                val = val[1:-1]
            variables[key] = val
    return variables


def substitute_placeholders(text: str, env: Dict[str, str]) -> str:
    """Заменяет ${VAR} из словаря env, оставляет плейсхолдер, если VAR не найден."""
    pattern = re.compile(r"\$\{([A-Za-z_][A-Za-z0-9_]*)\}")
    return pattern.sub(lambda m: env.get(m.group(1), m.group(0)), text)


def main() -> int:
    if len(sys.argv) != 3:
        sys.stderr.write(
            "Usage: substitute_env.py <env_path> <compose_path>\n"
        )
        return 2

    env_path, compose_path = sys.argv[1], sys.argv[2]

    if not os.path.exists(env_path):
        sys.stderr.write(f"Env file not found: {env_path}\n")
        return 3
    if not os.path.exists(compose_path):
        sys.stderr.write(f"Compose file not found: {compose_path}\n")
        return 4

    env = parse_env_file(env_path)

    with io.open(compose_path, "r", encoding="utf-8") as fh:
        content = fh.read()
    new_content = substitute_placeholders(content, env)
    with io.open(compose_path, "w", encoding="utf-8") as fh:
        fh.write(new_content)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())


