package com.knecon.fforesight.service.layoutparser.server;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;

import com.iqser.red.storage.commons.utils.FileSystemBackedStorageService;
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingFinishedEvent;
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingRequest;
import com.knecon.fforesight.service.layoutparser.internal.api.queue.LayoutParsingType;
import com.knecon.fforesight.service.layoutparser.processor.LayoutParsingPipeline;
import com.knecon.fforesight.service.layoutparser.server.utils.AbstractTest;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LayoutparserEnd2EndTest extends AbstractTest {

    @Autowired
    private LayoutParsingPipeline layoutParsingPipeline;

    @Disabled
    @Test
    public void testLayoutParserEndToEnd() {

        String filePath = "/home/kschuettler/Dokumente/TestFiles/tables with striketrough text.pdf";

        runForFile(filePath);
    }

    @Test
    @Disabled
    @SneakyThrows
    public void testLayoutParserEndToEndWithFolder() {

        String folder = "/home/kschuettler/Dokumente/TestFiles/large number of prod files";
        List<Path> pdfFiles = Files.walk(Path.of(folder))
                .filter(path -> path.getFileName().toString().endsWith(".pdf"))
                .sorted(Comparator.comparing(Path::getFileName))
                .peek(System.out::println)
                .toList();

        System.out.printf("Found %d pdf files to process %n", pdfFiles.size());
        AtomicInteger count = new AtomicInteger(0);
        pdfFiles.stream()
                .peek(path -> log.info("{}/{}-{}", count.getAndIncrement(), pdfFiles.size(), path.getFileName()))
                .forEach(path -> runForFile(path.toFile().toString()));
    }


    @SneakyThrows
    private void runForFile(String filePath) {

        String fileName = Path.of(filePath).getFileName().toString();
        File file;
        if (filePath.startsWith("files")) { // from resources
            file = new ClassPathResource(filePath).getFile();
        } else { // absolute path
            file = new File(filePath);
        }

        LayoutParsingRequest layoutParsingRequest = buildDefaultLayoutParsingRequest(fileName, LayoutParsingType.DOCUMINE, true);
        prepareStorage(layoutParsingRequest, file);

        LayoutParsingFinishedEvent finishedEvent = layoutParsingPipeline.parseLayoutAndSaveFilesToStorage(layoutParsingRequest);

        Arrays.stream(finishedEvent.message().split("\n"))
                .forEach(log::info);

        File tmpFile = new File("/tmp/layoutparserEND2END/" + fileName + "_VIEWER.pdf");
        assert tmpFile.getParentFile().exists() || tmpFile.getParentFile().mkdirs();

        storageService.downloadTo(TENANT_ID, layoutParsingRequest.viewerDocumentStorageId(), tmpFile);
    }


    @AfterEach
    public void cleanUpTmp() {

        ((FileSystemBackedStorageService) storageService).clearStorage();
    }

}
