"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _chai_spec_1 = require("./_chai.spec");
const GPS_1 = require("./GPS");
describe("parseGPSLocation", () => {
    const defaultOpts = { ignoreZeroZeroLatLon: false };
    it("should return empty object when no GPS data present", () => {
        const result = (0, GPS_1.parseGPSLocation)({}, defaultOpts);
        (0, _chai_spec_1.expect)(result).to.containSubset({ invalid: false });
    });
    it("should ignore zero coordinates when ignoreZeroZeroLatLon is true", () => {
        const tags = {
            GPSLatitude: 0,
            GPSLongitude: 0,
        };
        const result = (0, GPS_1.parseGPSLocation)(tags, { ignoreZeroZeroLatLon: true });
        (0, _chai_spec_1.expect)(result.invalid).to.eql(true);
        (0, _chai_spec_1.expect)(result.warnings?.some((w) => /Ignoring zero/.test(w))).to.eql(true, `Expected warning about zero coordinates, but got: ${result.warnings}`);
    });
    it("should process valid coordinates correctly", () => {
        const tags = {
            GPSLatitude: 40.7128,
            GPSLatitudeRef: "N",
            GPSLongitude: 74.006,
            GPSLongitudeRef: "W",
        };
        const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
        (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(40.7128);
        (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(-74.006);
    });
    it("should handle out of range coordinates", () => {
        const tags = {
            GPSLatitude: 90.1,
            GPSLongitude: 180.1,
        };
        const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
        (0, _chai_spec_1.expect)(result.invalid).to.eql(true);
        (0, _chai_spec_1.expect)(result.warnings).to.include("Invalid GPSLatitude: 90.1 is out of range");
        (0, _chai_spec_1.expect)(result.warnings).to.include("Invalid GPSLongitude: 180.1 is out of range");
    });
    describe("GeolocationPosition hemisphere handling", () => {
        it("should handle Northeast hemisphere coordinates", () => {
            const tags = {
                GPSLatitude: 35.6762,
                GPSLongitude: 139.6503,
                GeolocationPosition: "35.6762,139.6503", // Tokyo
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(35.6762);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(139.6503);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("N");
            (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("E");
            (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        });
        it("should handle Northwest hemisphere coordinates", () => {
            const tags = {
                GPSLatitude: 40.7128,
                GPSLongitude: -74.006, // Fixed: Input longitude should be negative
                GeolocationPosition: "40.7128,-74.0060", // New York
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(40.7128);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(-74.006);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("N");
            (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("W");
            (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        });
        it("should handle Southeast hemisphere coordinates", () => {
            const tags = {
                GPSLatitude: 33.8688,
                GPSLongitude: 151.2093,
                GeolocationPosition: "-33.8688,151.2093", // Sydney
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(-33.8688);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(151.2093);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("S");
            (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("E");
            (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        });
        it("should handle Southwest hemisphere coordinates", () => {
            const tags = {
                GPSLatitude: 33.9249,
                GPSLongitude: 70.9264,
                GeolocationPosition: "-33.9249,-70.9264", // Santiago
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(-33.9249);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(-70.9264);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("S");
            (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("W");
            (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        });
        it("should correct mismatched signs with GeolocationPosition", () => {
            const tags = {
                GPSLatitude: 33.9249, // Wrong sign
                GPSLongitude: 70.9264, // Wrong sign
                GPSLatitudeRef: "N", // Wrong ref
                GPSLongitudeRef: "E", // Wrong ref
                GeolocationPosition: "-33.9249,-70.9264", // Santiago (correct)
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(-33.9249);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(-70.9264);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("S");
            (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("W");
            (0, _chai_spec_1.expect)(result.warnings).to.include("Corrected GPSLatitude sign based on GeolocationPosition");
            (0, _chai_spec_1.expect)(result.warnings).to.include("Corrected GPSLongitude sign based on GeolocationPosition");
            (0, _chai_spec_1.expect)(result.warnings).to.include("Corrected GPSLatitudeRef to S based on GeolocationPosition");
            (0, _chai_spec_1.expect)(result.warnings).to.include("Corrected GPSLongitudeRef to W based on GeolocationPosition");
            (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        });
        it("should correct wrong signs in Northwest hemisphere", () => {
            const tags = {
                GPSLatitude: 40.7128,
                GPSLongitude: 74.006, // Wrong sign (positive instead of negative)
                GeolocationPosition: "40.7128,-74.0060", // New York (correct)
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(40.7128);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(-74.006);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("N");
            (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("W");
            (0, _chai_spec_1.expect)(result.warnings).to.include("Corrected GPSLongitude sign based on GeolocationPosition");
            (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        });
        it("should handle coordinates near the equator and prime meridian", () => {
            const tags = {
                GPSLatitude: 0.3476,
                GPSLongitude: 0.2345,
                GeolocationPosition: "0.3476,0.2345", // Near 0,0
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(0.3476);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(0.2345);
            (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("N");
            (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("E");
            (0, _chai_spec_1.expect)(result.invalid).to.eql(false);
        });
    });
    it("should handle mismatched ref and coordinate signs", () => {
        const tags = {
            GPSLatitude: -40.7128,
            GPSLatitudeRef: "N",
            GPSLongitude: -74.006,
            GPSLongitudeRef: "E",
        };
        const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
        (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("S");
        (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("W");
        (0, _chai_spec_1.expect)(result.warnings?.length).to.eql(2);
    });
    it("should handle missing ref values", () => {
        const tags = {
            GPSLatitude: 40.7128,
            GPSLongitude: -74.006,
        };
        const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
        (0, _chai_spec_1.expect)(result.result?.GPSLatitudeRef).to.eql("N");
        (0, _chai_spec_1.expect)(result.result?.GPSLongitudeRef).to.eql("W");
    });
    describe("invalid input handling", () => {
        it("should handle non-numeric latitude/longitude values", () => {
            const tags = {
                GPSLatitude: "invalid",
                GPSLongitude: "not-a-number",
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.warnings).to.have.length.greaterThan(0);
            (0, _chai_spec_1.expect)(result.warnings?.some((w) => w.includes("Error parsing GPSLatitude"))).to.be.true;
            (0, _chai_spec_1.expect)(result.warnings?.some((w) => w.includes("Error parsing GPSLongitude"))).to.be.true;
        });
        it("should handle invalid GeolocationPosition format", () => {
            const tags = {
                GPSLatitude: 40.7128,
                GPSLongitude: -74.006,
                GeolocationPosition: "invalid,format,here",
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.warnings).to.have.length.greaterThan(0);
            (0, _chai_spec_1.expect)(result.warnings?.some((w) => w.includes("Error parsing GeolocationPosition"))).to.be.true;
        });
        it("should handle undefined and null values", () => {
            const tags = {
                GPSLatitude: undefined,
                GPSLongitude: null,
                GPSLatitudeRef: undefined,
                GPSLongitudeRef: null,
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.invalid).to.be.false;
            (0, _chai_spec_1.expect)(result.warnings).to.have.length(0);
        });
        it("should handle extreme coordinate values", () => {
            const tags = {
                GPSLatitude: Number.MAX_VALUE,
                GPSLongitude: Number.MIN_VALUE,
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.invalid).to.be.true;
            (0, _chai_spec_1.expect)(result.warnings).to.have.length.greaterThan(0);
        });
        it("should handle NaN values", () => {
            const tags = {
                GPSLatitude: NaN,
                GPSLongitude: NaN,
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.warnings).to.have.length.greaterThan(0);
        });
        it("should handle invalid ref values", () => {
            const tags = {
                GPSLatitude: 40.7128,
                GPSLatitudeRef: "X", // Invalid ref
                GPSLongitude: -74.006,
                GPSLongitudeRef: "Y", // Invalid ref
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.warnings).to.have.length.greaterThan(0);
            (0, _chai_spec_1.expect)(result.warnings?.some((w) => w.includes("Invalid GPSLatitudeRef")))
                .to.be.true;
            (0, _chai_spec_1.expect)(result.warnings?.some((w) => w.includes("Invalid GPSLongitudeRef"))).to.be.true;
        });
    });
    describe("edge cases", () => {
        it("should handle coordinates at exact poles", () => {
            const tags = {
                GPSLatitude: 90,
                GPSLongitude: 0,
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.invalid).to.be.false;
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(90);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(0);
        });
        it("should handle coordinates at the international date line", () => {
            const tags = {
                GPSLatitude: 0,
                GPSLongitude: 180,
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.invalid).to.be.false;
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.eql(0);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.eql(180);
        });
        it("should handle fractional zero coordinates", () => {
            const tags = {
                GPSLatitude: 0.0000001,
                GPSLongitude: -0.0000001,
            };
            const result = (0, GPS_1.parseGPSLocation)(tags, defaultOpts);
            (0, _chai_spec_1.expect)(result.invalid).to.be.false;
            (0, _chai_spec_1.expect)(result.result?.GPSLatitude).to.be.closeTo(0, 0.0000001);
            (0, _chai_spec_1.expect)(result.result?.GPSLongitude).to.be.closeTo(0, 0.0000001);
        });
    });
});
//# sourceMappingURL=GPS.spec.js.map