package ai.decompile.analysis.controller;

import ai.decompile.analysis.model.dto.AnalysisResponse;
import ai.decompile.analysis.model.dto.DataLabelResponse;
import ai.decompile.analysis.model.dto.EnumResponse;
import ai.decompile.analysis.model.dto.FunctionSummaryResponse;
import ai.decompile.analysis.model.dto.ImportResponse;
import ai.decompile.analysis.model.dto.SegmentResponse;
import ai.decompile.analysis.model.dto.StringResponse;
import ai.decompile.analysis.model.dto.StructResponse;
import ai.decompile.analysis.service.AnalysisService;
import io.swagger.v3.oas.annotations.Operation;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
public class AnalysisController {
  private final AnalysisService analysisService;

  @Operation(
      summary = "List static analyses for a binary",
      description = "Retrieve all static analyses performed on a binary.",
      tags = {"Analysis"},
      operationId = "listAnalyses")
  @GetMapping("/binaries/{binaryId}/analysis")
  public List<AnalysisResponse> listAnalyses(@PathVariable UUID binaryId) {
    return analysisService.listAnalyses(binaryId);
  }

  @Operation(
      summary = "Get static analysis details",
      description = "Retrieve details of a specific static analysis.",
      tags = {"Analysis"},
      operationId = "getAnalysis")
  @GetMapping("/analysis/{analysisId}")
  public AnalysisResponse getAnalysis(@PathVariable UUID analysisId) {
    return analysisService.getAnalysis(analysisId);
  }

  @Operation(
      summary = "List functions in an analysis",
      description = "Retrieve paginated list of functions extracted during a static analysis.",
      tags = {"Analysis"},
      operationId = "listFunctions")
  @GetMapping("/analysis/{analysisId}/functions")
  public Page<FunctionSummaryResponse> listFunctions(
      @PathVariable UUID analysisId, Pageable pageable) {
    return analysisService.listFunctions(analysisId, pageable);
  }

  @Operation(
      summary = "List segments in an analysis",
      description =
          "Retrieve memory segments (code, data, etc.) identified during a static analysis.",
      tags = {"Analysis"},
      operationId = "listSegments")
  @GetMapping("/analysis/{analysisId}/segments")
  public List<SegmentResponse> getSegments(@PathVariable UUID analysisId) {
    return analysisService.getSegments(analysisId);
  }

  @Operation(
      summary = "List strings in an analysis",
      description = "Retrieve all strings extracted during a static analysis.",
      tags = {"Analysis"},
      operationId = "listStrings")
  @GetMapping("/analysis/{analysisId}/strings")
  public List<StringResponse> getStrings(@PathVariable UUID analysisId) {
    return analysisService.getStrings(analysisId);
  }

  @Operation(
      summary = "List imports in an analysis",
      description = "Retrieve all imported DLL functions identified during a static analysis.",
      tags = {"Analysis"},
      operationId = "listImports")
  @GetMapping("/analysis/{analysisId}/imports")
  public List<ImportResponse> getImports(@PathVariable UUID analysisId) {
    return analysisService.getImports(analysisId);
  }

  @Operation(
      summary = "List global variables in an analysis",
      description =
          "Retrieve all named data labels (global variables) identified during a static analysis.",
      tags = {"Analysis"},
      operationId = "listGlobalVars")
  @GetMapping("/analysis/{analysisId}/global-vars")
  public List<DataLabelResponse> getGlobalVars(@PathVariable UUID analysisId) {
    return analysisService.getGlobalVars(analysisId);
  }

  @Operation(
      summary = "List structures in an analysis",
      description = "Retrieve all struct/union definitions identified during a static analysis.",
      tags = {"Analysis"},
      operationId = "listStructures")
  @GetMapping("/analysis/{analysisId}/structures")
  public List<StructResponse> getStructures(@PathVariable UUID analysisId) {
    return analysisService.getStructures(analysisId);
  }

  @Operation(
      summary = "List enums in an analysis",
      description = "Retrieve all enum definitions identified during a static analysis.",
      tags = {"Analysis"},
      operationId = "listEnums")
  @GetMapping("/analysis/{analysisId}/enums")
  public List<EnumResponse> getEnums(@PathVariable UUID analysisId) {
    return analysisService.getEnums(analysisId);
  }
}
