using System;
using System.IO;
using dataladder.Data;
using dataladder.Licensing;
using dataladder.Matching;
using DataMatching.Matching;
using MatchEngineSample;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MatchingTests
{
    [TestClass]
    public class TestMatching
    {
        [TestMethod]
        public void TestMatchManager()
        {
            dataladder.Matching.ApplicationSettings.Load();
            RegistrationWrapper registration = new RegistrationWrapper();
            registration.CustomPathForRegistrationFile = @"D:\API\registration2\";
            DateTime expirationDate = RegistrationWrapper.ExpirationDate;

            bool registered = dataladder.Licensing.Registration.GlobalRegistrationInstance.Check(out DateTime expirationData, out String message);
            Assert.AreEqual(registered, true);

            // Create Match Settings
            MatchSettings matchSettings = new MatchSettings();
            matchSettings.DataPath = @"D:\API\Data";
            matchSettings.TempPath = @"D:\API\Temp";
            matchSettings.Name = "TestEngine";

            // 1. Init Data Source
            String sourceTableName = "Source1";
            String tableFullPath = Path.Combine(matchSettings.DataPath, matchSettings.Name);
            MatchingSample.CreateOrClearFolder(tableFullPath);

            OnDriveTable onDriveTable = new OnDriveTable(tableFullPath, sourceTableName);
            onDriveTable.ToDeleteFilesAfterClosing = true;
            onDriveTable.AddField("FirstName", typeof(String));
            onDriveTable.AddField("LastName", typeof(String));
            onDriveTable.SetData("John", 0, 0);
            onDriveTable.SetData("Smith", 0, 1);
            onDriveTable.SetData("Joan", 1, 0);
            onDriveTable.SetData("Smit", 1, 1);
            onDriveTable.SetData("Anna", 2, 0);
            onDriveTable.SetData("Taylor", 2, 1);

            // 2. Init Match Definition Manager
            MultipleMatchDefinitionsManager matchDefinitionManager = new MultipleMatchDefinitionsManager();

            MatchCriteriaList matchCriteriaList = new MatchCriteriaList(0);
            MatchCriteria firstNameCriteria = new MatchCriteria()
            {
                Fuzzy = true,
                AddWeightToFirstLetter = false,
                Exact = false,
                Numeric = false,
                UseMetaphone = false,
                IgnoreCase = true,
                Level = 0.7f,
                GroupLevel = 0.0f,
                MinAllowedLevelInGroup = 0.0f,
                GroupId = -1,
                CrossColumnGroupId = -1,
                Weight = 100.0f,
                MatchingIndex = 0,
                AbsoluteMatchingIndex = 0
            };

            firstNameCriteria.MapField(sourceTableName, "FirstName");

            matchCriteriaList.Add(firstNameCriteria);
            matchCriteriaList.MarkTheFirstFieldInEveryGroup();

            matchDefinitionManager.Add(matchCriteriaList);

            AvailableFieldsFromOneTable fieldsFromTable = new AvailableFieldsFromOneTable();
            fieldsFromTable.Table = onDriveTable;

            FieldMapInfo fmiFirstName = new FieldMapInfo(0);
            fmiFirstName.FieldName = "FirstName";
            fmiFirstName.TableName = sourceTableName;
            fmiFirstName.ColumnTransformation = null;
            fmiFirstName.FieldIndex = 0;
            fieldsFromTable.Add(fmiFirstName);

            FieldMapInfo fmiLastName = new FieldMapInfo(0);
            fmiLastName.FieldName = "LastName";
            fmiLastName.TableName = sourceTableName;
            fmiLastName.ColumnTransformation = null;
            fmiLastName.FieldIndex = 1;
            fieldsFromTable.Add(fmiLastName);

            matchDefinitionManager.AvailableFields = new AvailableFields();


            matchDefinitionManager.AvailableFields.TableList.Add(fieldsFromTable);

            MappedFieldsRow mfrFirstName = new MappedFieldsRow();
            mfrFirstName[sourceTableName] = fmiFirstName;
            matchDefinitionManager.AvailableFields.MappedFieldsRowList.Add(mfrFirstName);

            MappedFieldsRow mfrLastName = new MappedFieldsRow();
            mfrLastName[sourceTableName] = fmiLastName;
            matchDefinitionManager.AvailableFields.MappedFieldsRowList.Add(mfrLastName);

            matchDefinitionManager.SetAbsoluteIndices();

            // Finish init settings
            matchSettings.MatchDefinitionManager = matchDefinitionManager;
            matchSettings.Tables.Add(onDriveTable);
            matchSettings.SourcePairs.Add(new MatchEngine.DataSourceIndexPair(0, 0));

            MatchManager matchManager = new MatchManager(matchSettings);
            matchManager.FindMatches();

            OnDriveTable groupsTable = matchSettings.FinalScoresGroupsTable;
            Assert.AreEqual(groupsTable.RecordCount, 2);

            OnDriveTable pairsTable = matchSettings.PairsScoresTable;
            Assert.AreEqual(pairsTable.RecordCount, 2);

            onDriveTable.Dispose();
        }
    }
}
