using EDPlayerJournal;
using EDPlayerJournal.BGS;
using EDPlayerJournal.Entries;

namespace EDPlayerJournalTests;

[TestClass]
public class TestTransactionParser {
    [TestMethod]
    public void Legacy() {
        TransactionParser parser = new();

        // File header, followed by two legacy transactions, followed by another
        // file header with an Odyssey transaction
        List<Entry>? entries = Helper.LoadTestData("legacy-transaction.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        var options = new TransactionParserOptions() {
            IgnoreInfluenceSupport = false,
            IgnoreExoBiology = false,
            IgnoreFleetCarrierFaction = false,
            IgnoreMarketBuy = false,
        };
        List<Transaction>? transactions = parser.Parse(entries, options);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 3);

        Assert.AreEqual(transactions[0].IsLegacy, true);
        Assert.AreEqual(transactions[1].IsLegacy, true);

        Assert.AreEqual(transactions[2].IsLegacy, false);
    }

    [TestMethod]
    public void DoubleFiveINF() {
        TransactionParser parser = new();

        List<Entry>? entries = Helper.LoadTestData("double-five-inf.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        List<Transaction>? transactions = parser.Parse(entries);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 10);
    }

    [TestMethod]
    public void DoubleSupport() {
        TransactionParser parser = new();

        List<Entry>? entries = Helper.LoadTestData("double-support.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        List<Transaction>? transactions = parser.Parse(entries);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 16);
    }

    [TestMethod]
    public void MissionFailed() {
        TransactionParser parser = new();

        List<Entry>? entries = Helper.LoadTestData("mission-failed.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        List<Transaction>? transactions = parser.Parse(entries);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 18);
    }

    [TestMethod]
    public void MissionNoINF() {
        TransactionParser parser = new();

        List<Entry>? entries = Helper.LoadTestData("mission-noinfforsourceortarget.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        List<Transaction>? transactions = parser.Parse(entries);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 10);
    }

    [TestMethod]
    public void Murder() {
        TransactionParser parser = new();

        List<Entry>? entries = Helper.LoadTestData("murder.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        List<Transaction>? transactions = parser.Parse(entries);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 1);

        if (transactions == null) {
            return;
        }

        FoulMurder? murder = transactions[0] as FoulMurder;
        Assert.IsNotNull(murder, "result is not a murder");
        Assert.AreEqual(murder.Faction, "Dei Muata Society");
    }

    [TestMethod]
    public void NoFactionNameNoInfluence() {
        TransactionParser parser = new();

        List<Entry>? entries = Helper.LoadTestData("nofactionname-andnoinfluence.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        List<Transaction>? transactions = parser.Parse(entries);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 1);
    }

    [TestMethod]
    public void SellOrganicData() {
        TransactionParser parser = new();

        List<Entry>? entries = Helper.LoadTestData("SellOrganicData.txt");
        Assert.IsNotNull(entries, "could not load test data");

        if (entries == null) {
            return;
        }

        var options = new TransactionParserOptions() {
            IgnoreInfluenceSupport = false,
            IgnoreExoBiology = false,
            IgnoreFleetCarrierFaction = false,
            IgnoreMarketBuy = false,
        };

        List<Transaction>? transactions = parser.Parse(entries, options);
        Assert.IsNotNull(transactions, "could not parse entries");
        Assert.AreEqual(transactions.Count, 1);
        Assert.IsInstanceOfType(transactions[0], typeof(OrganicData), "result is not of type Organic Data");
    }
}