package com.printcalculator.service;

import com.printcalculator.model.PrintStats;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import static org.junit.jupiter.api.Assertions.*;

class GCodeParserTest {

    @Test
    void parse_validGcode_returnsCorrectStats() throws IOException {
        // Arrange
        File tempFile = File.createTempFile("test", ".gcode");
        try (FileWriter writer = new FileWriter(tempFile)) {
            writer.write("; generated by OrcaSlicer\n");
            writer.write("; estimated printing time = 1h 2m 3s\n");
            writer.write("; filament used [g] = 10.5\n");
            writer.write("; filament used [mm] = 3000.0\n");
        }

        GCodeParser parser = new GCodeParser();

        // Act
        PrintStats stats = parser.parse(tempFile);

        // Assert
        assertEquals(3723, stats.printTimeSeconds()); // 3600 + 120 + 3
        assertEquals("1h 2m 3s", stats.printTimeFormatted());
        assertEquals(10.5, stats.filamentWeightGrams(), 0.001);
        assertEquals(3000.0, stats.filamentLengthMm(), 0.001);

        tempFile.delete();
    }
    
    @Test
    void parse_footerGcode_returnsCorrectStats() throws IOException {
        // Arrange
        File tempFile = File.createTempFile("test_footer", ".gcode");
        try (FileWriter writer = new FileWriter(tempFile)) {
            writer.write("; header\n");
             // ... many lines ...
            writer.write("; filament used [g] = 5.0\n");
            writer.write("; estimated printing time = 12m 30s\n");
        }

        GCodeParser parser = new GCodeParser();
        PrintStats stats = parser.parse(tempFile);

        assertEquals(750, stats.printTimeSeconds()); // 12*60 + 30
        assertEquals(5.0, stats.filamentWeightGrams(), 0.001);

        tempFile.delete();
    }
    @Test
    void parse_withExtraTextInTimeLine_returnsCorrectStats() throws IOException {
        // Arrange
        File tempFile = File.createTempFile("test_extra", ".gcode");
        try (FileWriter writer = new FileWriter(tempFile)) {
            writer.write("; generated by OrcaSlicer\n");
            // Simulate the variation that was causing issues
            writer.write("; estimated printing time (normal mode) = 1h 2m 3s\n"); 
            writer.write("; filament used [g] = 10.5\n");
            writer.write("; filament used [mm] = 3000.0\n");
        }

        GCodeParser parser = new GCodeParser();
        PrintStats stats = parser.parse(tempFile);

        assertEquals(3723L, stats.printTimeSeconds()); 
        assertEquals("1h 2m 3s", stats.printTimeFormatted());

        tempFile.delete();
    }

    @Test
    void parse_colonFormattedTime_returnsCorrectStats() throws IOException {
        File tempFile = File.createTempFile("test_colon", ".gcode");
        try (FileWriter writer = new FileWriter(tempFile)) {
            writer.write("; generated by OrcaSlicer\n");
            writer.write("; print time: 01:02:03\n");
            writer.write("; filament used [g] = 7.5\n");
        }

        GCodeParser parser = new GCodeParser();
        PrintStats stats = parser.parse(tempFile);

        assertEquals(3723L, stats.printTimeSeconds());
        assertEquals("01:02:03", stats.printTimeFormatted());

        tempFile.delete();
    }

    @Test
    void parse_totalEstimatedTimeInline_returnsCorrectStats() throws IOException {
        File tempFile = File.createTempFile("test_total", ".gcode");
        try (FileWriter writer = new FileWriter(tempFile)) {
            writer.write("; generated by OrcaSlicer\n");
            writer.write("; model printing time: 5m 17s; total estimated time: 5m 21s\n");
            writer.write("; filament used [g] = 2.0\n");
        }

        GCodeParser parser = new GCodeParser();
        PrintStats stats = parser.parse(tempFile);

        assertEquals(321L, stats.printTimeSeconds());
        assertEquals("5m 21s", stats.printTimeFormatted());

        tempFile.delete();
    }
}
