// tests/test_motor.cpp

#include "vendor/catch_amalgamated.hpp"
#include "Motor.h"

// Bring Approx into local scope
using Catch::Approx;

TEST_CASE("Motor basic behavior", "[motor]") {
    Motor testMotor("TestMotor", 0.05, 50.0); // 50 grams propellant, 50 Ns impulse

    SECTION("Motor should not be ignited at start") {
        REQUIRE(testMotor.isBurnedOut() == false);
        REQUIRE(testMotor.getCurrentThrust() == Approx(0.0));
    }

    SECTION("Motor thrust curve points can be added") {
        testMotor.addThrustDataPoint(0.0, 0.0);
        testMotor.addThrustDataPoint(0.5, 100.0);
        testMotor.addThrustDataPoint(1.0, 0.0);

        testMotor.ignite();
        testMotor.update(0.25); // halfway to 0.5 seconds

        // Should interpolate between 0 and 100 N
        REQUIRE(testMotor.getCurrentThrust() > 0.0);
        REQUIRE(testMotor.isBurnedOut() == false);
    }

    SECTION("Motor ignition starts thrust production") {
        testMotor.addThrustDataPoint(0.0, 0.0);
        testMotor.addThrustDataPoint(0.1, 50.0);
        testMotor.addThrustDataPoint(1.5, 50.0);
        testMotor.addThrustDataPoint(1.6, 0.0);

        testMotor.ignite();
        testMotor.update(0.1); // 100ms

        REQUIRE(testMotor.getCurrentThrust() > 0.0);
        REQUIRE(testMotor.isBurnedOut() == false);
    }

    SECTION("Motor burns out after thrust curve ends") {
        testMotor.addThrustDataPoint(0.0, 0.0);
        testMotor.addThrustDataPoint(0.5, 50.0);
        testMotor.addThrustDataPoint(1.0, 0.0);

        testMotor.ignite();
        testMotor.update(2.0); // 2 seconds, way past end

        REQUIRE(testMotor.isBurnedOut() == true);
        REQUIRE(testMotor.getCurrentThrust() == Approx(0.0));
    }

    SECTION("Remaining propellant decreases over time") {
        testMotor.addThrustDataPoint(0.0, 0.0);
        testMotor.addThrustDataPoint(0.5, 100.0);
        testMotor.addThrustDataPoint(1.0, 0.0);

        testMotor.ignite();
        double initialMass = testMotor.getRemainingPropellantMass();
        
        testMotor.update(0.5); // Burn for 0.5 seconds

        double remainingMass = testMotor.getRemainingPropellantMass();
        REQUIRE(remainingMass < initialMass);
        REQUIRE(remainingMass >= 0.0);
    }
}
