package com.kamco.cd.training.train.service;

import com.kamco.cd.training.postgres.core.ModelTestMetricsJobCoreService;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class ModelTestMetricsJobService {

  private final ModelTestMetricsJobCoreService modelTestMetricsJobCoreService;

  @Value("${spring.profiles.active}")
  private String profile;

  /**
   * 실행중인 profile
   *
   * @return
   */
  private boolean isLocalProfile() {
    return "local".equalsIgnoreCase(profile);
  }

  //  @Scheduled(cron = "0 0/10 * * * *")
  public void findTestValidMetricCsvFiles() {
    if (isLocalProfile()) {
      return;
    }

    List<Long> modelIds =
        modelTestMetricsJobCoreService
            .getTestMetricSaveNotYetModelIds(); // TODO: uid, uuid ? 가져오기로 해야함

    if (modelIds.isEmpty()) {
      return;
    }

    String localPath = "C:\\data\\upload\\test.csv";
    try (BufferedReader reader =
        Files.newBufferedReader(Paths.get(localPath), StandardCharsets.UTF_8); ) {

      log.info("### localPath={}", localPath);
      CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);

      List<Object[]> batchArgs = new ArrayList<>();

      for (CSVRecord record : parser) {

        String model = record.get("model");
        long TP = Long.parseLong(record.get("TP"));
        long FP = Long.parseLong(record.get("FP"));
        long FN = Long.parseLong(record.get("FN"));
        float precision = Float.parseFloat(record.get("precision"));
        float recall = Float.parseFloat(record.get("recall"));
        float f1_score = Float.parseFloat(record.get("f1_score"));
        float accuracy = Float.parseFloat(record.get("accuracy"));
        float iou = Float.parseFloat(record.get("iou"));
        long detection_count = Long.parseLong(record.get("detection_count"));
        long gt_count = Long.parseLong(record.get("gt_count"));

        batchArgs.add(
            new Object[] {
              modelIds.getFirst(),
              model,
              TP,
              FP,
              FN,
              precision,
              recall,
              f1_score,
              accuracy,
              iou,
              detection_count,
              gt_count
            });
      }

      modelTestMetricsJobCoreService.insertModelMetricsTest(batchArgs);

    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    modelTestMetricsJobCoreService.updateModelMetricsTrainSaveYn(modelIds.getFirst(), "step2");
  }
}
