package ai.decompile.die.service;

import ai.decompile.die.model.DieResult;
import ai.decompile.docker.service.ContainerService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.dockerjava.api.model.Bind;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

@Log4j2
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(name = "app.docker.enabled", havingValue = "true")
public class DiecService {
  private final ContainerService containers;
  private final ObjectMapper objectMapper;

  @Value("${app.die.image}")
  private String imageName;

  @Value("${app.storage.upload-dir}")
  private String uploadDir;

  @Value("${app.die.timeout-seconds}")
  private long timeoutSeconds;

  public DieResult analyze(String filePath) {
    var absolutePath = Path.of(uploadDir).resolve(filePath).toAbsolutePath().normalize();
    var filename = absolutePath.getFileName().toString();
    var hostPath = absolutePath.getParent().toString();

    var dockerfile = new File("Dockerfile.die");
    containers.ensureImage(imageName, dockerfile);

    var bind = Bind.parse(hostPath + ":/input:ro");

    var containerId =
        containers.createContainer(imageName, new String[] {"--json", "/input/" + filename}, bind);

    try {
      containers.startContainer(containerId);

      var exitCode = containers.waitForExit(containerId, timeoutSeconds);
      var stdout = containers.captureLogs(containerId, 2);

      if (exitCode != 0) {
        log.error("DiE container exited with code {}: {}", exitCode, stdout);
        throw new RuntimeException(
            "DiE container exited with code " + exitCode + ". Output: " + stdout);
      }

      return objectMapper.readValue(stdout, DieResult.class);
    } catch (IOException e) {
      log.error("DiE analysis failed for file {}: {}", filePath, e.getMessage());
      throw new RuntimeException("DiE analysis failed: " + e.getMessage(), e);
    } finally {
      containers.stopAndRemove(containerId);
    }
  }
}
