package com.pandoli365.bibimbap.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.UUID;
import java.util.stream.Stream;

@Service
public class GameAssetCleanupService {

    private static final Logger log = LoggerFactory.getLogger(GameAssetCleanupService.class);

    @Value("${app.upload.game-storage-path:src/main/resources/static}")
    private String uploadStoragePath;

    /**
     * webgl_path("/game/{uuid}/index.html")의 UUID 디렉터리를 경계 내에서 hard-delete 한다.
     * 입력이 비정상이거나 대상이 없으면 무동작(멱등). 정리 실패는 호출 트랜잭션을 깨지 않도록 삼킨다.
     */
    public void purgeByWebglPath(String webglPath) {
        if (webglPath == null || webglPath.isBlank()) {
            return;
        }
        if (!webglPath.startsWith("/game/")) {
            return;
        }
        String[] parts = webglPath.split("/");
        if (parts.length <= 2 || parts[2].isBlank()) {
            return;
        }

        String normalizedUuid;
        try {
            // 비-UUID 토큰(경계 밖/조작 입력)은 거부
            normalizedUuid = UUID.fromString(parts[2]).toString();
        } catch (IllegalArgumentException e) {
            return;
        }

        Path root = gameRoot();
        Path target = root.resolve(normalizedUuid).normalize();
        if (!target.startsWith(root) || target.equals(root)) {
            return;
        }
        if (!Files.isDirectory(target)) {
            return;
        }

        try {
            deleteRecursively(target);
        } catch (IOException e) {
            log.warn("게임 자산 정리 실패. webglPath={}, target={}", webglPath, target, e);
        }
    }

    private Path gameRoot() {
        return Paths.get(uploadStoragePath).toAbsolutePath().normalize().resolve("game").normalize();
    }

    private void deleteRecursively(Path path) throws IOException {
        if (!Files.exists(path)) {
            return;
        }
        try (Stream<Path> paths = Files.walk(path)) {
            for (Path target : paths.sorted(Comparator.reverseOrder()).toList()) {
                Files.deleteIfExists(target);
            }
        }
    }
}
