using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Pluto.Api;
using Sdaleo.Systems.SQLServer;
using Connector = PlutoServer.MSL.Connectors;

namespace PlutoServer.MSL.Test
{
    [TestFixture]
    public class LytecConnector
    {
        #region Lytec Test Connection

        const string LYTEC_KEY = "$616866C0D12EC1641A5#L";
        public SQLServerCredential credential = new SQLServerCredential("10.97.156.22","LytecMD","Lytec Tutorial", "sa", "Clinical$1");

        #endregion

        [SetUp]
        public void Init()
        {
            MSLSpecific.Setup_Test_Logger();
            Connector.DBCache.IsMachine_Used_ForTesting = true;
            Connector.DBCache.TestLytecUserDBCredential = credential;
        }

        [Test]
        public void GetProviderList()
        {
            ProviderInfo1[] providers = Connector.LytecConnector.GetProviderList(LYTEC_KEY);
            Assert.NotNull(providers);
            if (providers != null)
            {
                Assert.True(providers.Length > 0);
                if (providers.Length > 0)
                {
                    foreach (ProviderInfo1 info in providers)
                    {
                        // User ID must exist for provider
                        Assert.IsNotNullOrEmpty(info.UserId);

                        // Assume the provider has at least one name field filled out
                        Assert.True(!String.IsNullOrEmpty(info.LastName) || !String.IsNullOrEmpty(info.FirstName) || !String.IsNullOrEmpty(info.MiddleName));
                    }
                }
            }
        }

        [Test]
        public void GetPatientList()
        {
            PatientInfo1[] patients = Connector.LytecConnector.GetPatientList(LYTEC_KEY, "", "", "");
            Assert.NotNull(patients);
            if (patients != null)
            {
                Assert.True(patients.Length > 0);
                if (patients.Length > 0)
                {
                    foreach (PatientInfo1 info in patients)
                    {
                        // Chart must exist for patients
                        Assert.IsNotNullOrEmpty(info.ChartId);

                        // Assume the patient has at least one name field filled out
                        Assert.True(!String.IsNullOrEmpty(info.LastName) || !String.IsNullOrEmpty(info.FirstName) || !String.IsNullOrEmpty(info.MiddleName));
                    }
                }
            }
        }

        [Test]
        public void GetPatient_Caesar_J()
        {
            PatientInfo1[] patients = Connector.LytecConnector.GetPatientList(LYTEC_KEY, "Caesar", "J", "");
            Assert.NotNull(patients);
            if (patients != null)
            {
                Assert.True(patients.Length > 0);
                if (patients.Length > 0)
                {
                    foreach (PatientInfo1 info in patients)
                    {
                        // Chart must exist for patients
                        Assert.IsNotNullOrEmpty(info.ChartId);

                        // Assume the patient has at least one name field filled out
                        Assert.True(!String.IsNullOrEmpty(info.LastName) || !String.IsNullOrEmpty(info.FirstName) || !String.IsNullOrEmpty(info.MiddleName));

                        // Check For John and Jane Doe
                        if (info.LastName == "Caesar")
                            Assert.True(info.FirstName == "Jay" || info.FirstName == "Julie");
                    }
                }
            }
        }

        [Test]
        public void GetPatient_C()
        {
            PatientInfo1[] patients = Connector.LytecConnector.GetPatientList(LYTEC_KEY, "C", "", "");
            Assert.NotNull(patients);
            if (patients != null)
            {
                Assert.True(patients.Length > 0);
                if (patients.Length > 0)
                {
                    foreach (PatientInfo1 info in patients)
                    {
                        // Chart must exist for patients
                        Assert.IsNotNullOrEmpty(info.ChartId);

                        // Assume the patient has at least one name field filled out
                        Assert.True(!String.IsNullOrEmpty(info.LastName) || !String.IsNullOrEmpty(info.FirstName) || !String.IsNullOrEmpty(info.MiddleName));

                        // Check to make sure last name contains a C
                        Assert.True(info.LastName.ToUpper().Contains("C"));
                    }
                }
            }
        }

        [Test]
        public void GetPatient_DOB()
        {
            PatientInfo1[] patients = Connector.LytecConnector.GetPatientList(LYTEC_KEY, "", "", "01/10/1975");
            Assert.NotNull(patients);
            if (patients != null)
            {
                Assert.True(patients.Length == 1);
                if (patients.Length == 1)
                {
                    foreach (PatientInfo1 info in patients)
                    {
                        // Chart must exist for patients
                        Assert.IsNotNullOrEmpty(info.ChartId);

                        // Assume the patient has at least one name field filled out
                        Assert.True(!String.IsNullOrEmpty(info.LastName) || !String.IsNullOrEmpty(info.FirstName) || !String.IsNullOrEmpty(info.MiddleName));

                        // Check to make sure last name is DOE
                        Assert.True(info.LastName.ToUpper() == "DE LA ROSA");

                        // Check to make sure first name is Jane
                        Assert.True(info.FirstName.ToUpper() == "ROSA");
                    }
                }
            }
        }

        [Test]
        public void GetFacilitiesList()
        {
            FacilityInfo1[] facilities = Connector.LytecConnector.GetFacilitiesList(LYTEC_KEY);
            Assert.NotNull(facilities);
            if (facilities != null)
            {
                Assert.True(facilities.Length > 0);
                if (facilities.Length > 0)
                {
                    foreach (FacilityInfo1 info in facilities)
                    {
                        // Code must exist for each facility
                        Assert.IsNotNullOrEmpty(info.Code);

                        // Assume the facility has at least a name
                        Assert.True(!String.IsNullOrEmpty(info.Name));
                    }
                }
            }
        }

        [Test]
        public void GetDiagnosisList()
        {
            TerminologyInfo1[] diagnoses = Connector.LytecConnector.GetDiagnosisList(LYTEC_KEY, String.Empty);
            Assert.NotNull(diagnoses);
            if (diagnoses != null)
            {
                Assert.True(diagnoses.Length > 0);
                if (diagnoses.Length > 0)
                {
                    foreach (TerminologyInfo1 info in diagnoses)
                    {
                        // Code must exist for each Diagnosis
                        Assert.IsNotNullOrEmpty(info.Code);

                        // Description must exist for each Diagnosis
                        Assert.IsNotNullOrEmpty(info.Description);
                    }
                }
            }
        }

        [Test]
        public void GetDiagnosis_1()
        {
            TerminologyInfo1[] diagnoses = Connector.LytecConnector.GetDiagnosisList(LYTEC_KEY, "1");
            Assert.NotNull(diagnoses);
            if (diagnoses != null)
            {
                Assert.True(diagnoses.Length > 0);
                if (diagnoses.Length > 0)
                {
                    foreach (TerminologyInfo1 info in diagnoses)
                    {
                        // Code must exist for each Diagnosis
                        Assert.IsNotNullOrEmpty(info.Code);

                        // Description must exist for each Diagnosis
                        Assert.IsNotNullOrEmpty(info.Description);

                        // Code or Description must contain a "1"
                        Assert.True(info.Code.Contains("1") || info.Description.Contains("1"));
                    }
                }
            }
        }

        [Test]
        public void GetDiagnosis_Dia()
        {
            TerminologyInfo1[] diagnoses = Connector.LytecConnector.GetDiagnosisList(LYTEC_KEY, "Dia");
            Assert.NotNull(diagnoses);
            if (diagnoses != null)
            {
                Assert.True(diagnoses.Length > 0);
                if (diagnoses.Length > 0)
                {
                    foreach (TerminologyInfo1 info in diagnoses)
                    {
                        // Code must exist for each Diagnosis
                        Assert.IsNotNullOrEmpty(info.Code);

                        // Description must exist for each Diagnosis
                        Assert.IsNotNullOrEmpty(info.Description);

                        // Code or Description must contain a "1"
                        Assert.True(info.Code.Contains("Dia") || info.Description.Contains("Dia"));
                    }
                }
            }
        }

        [Test]
        public void GetProcedureList()
        {
            TerminologyInfo1[] procedures = Connector.LytecConnector.GetProceduresList(LYTEC_KEY, String.Empty, String.Empty);
            Assert.NotNull(procedures);
            if (procedures != null)
            {
                Assert.True(procedures.Length > 0);
                if (procedures.Length > 0)
                {
                    foreach (TerminologyInfo1 info in procedures)
                    {
                        // Code must exist for each procedures
                        Assert.IsNotNullOrEmpty(info.Code);

                        // Description must exist for each procedures
                        Assert.IsNotNullOrEmpty(info.Description);
                    }
                }
            }
        }

        [Test]
        public void GetProcedure_1()
        {
            TerminologyInfo1[] procedures = Connector.LytecConnector.GetProceduresList(LYTEC_KEY, String.Empty, "1");
            Assert.NotNull(procedures);
            if (procedures != null)
            {
                Assert.True(procedures.Length > 0);
                if (procedures.Length > 0)
                {
                    foreach (TerminologyInfo1 info in procedures)
                    {
                        // Code must exist for each procedures
                        Assert.IsNotNullOrEmpty(info.Code);

                        // Description must exist for each procedures
                        Assert.IsNotNullOrEmpty(info.Description);

                        // Code or Description must contain a "1"
                        Assert.True(info.Code.Contains("1") || info.Description.Contains("1"));
                    }
                }
            }
        }

        [Test]
        public void Authenticate_System()
        {
            UserInfo1 info = Connector.LytecConnector.AuthenticateUserLogin(LYTEC_KEY, "system", "system1");
            Assert.NotNull(info);
            if (info != null)
            {
                // Username must exist
                Assert.IsNotNullOrEmpty(info.UserName);

                // Name must exist
                Assert.IsNotNullOrEmpty(info.Name);
            }
        }

        [Test]
        public void Authenticate_98()
        {
            UserInfo1 info = Connector.LytecConnector.AuthenticateUserLogin(LYTEC_KEY, "98", "2");
            Assert.Null(info);
        }

        /// <summary>
        /// Assumes that the User 1 has a Pin of 1234 (that is what should be setup in the UI by default)
        /// </summary>
        [Test]
        public void AuthenticatePin_1()
        {
            Assert.True(Connector.LytecConnector.PinIsSet(LYTEC_KEY, "system"));
            UserInfo1 info = Connector.LytecConnector.AuthenticateUserPIN(LYTEC_KEY, "system", "1212");
            Assert.NotNull(info);
            if (info != null)
            {
                // Username must exist
                Assert.IsNotNullOrEmpty(info.UserName);

                // Name must exist
                Assert.IsNotNullOrEmpty(info.Name);
            }
        }

        /// <summary>
        /// Sets the Pin to an arbitrary value for User 1, and checks if that authenticates, then
        /// resets the pin back to the original value 1234
        /// </summary>
        [Test]
        public void SetNAuthenticateNResetPin_1()
        {
            Assert.True(Connector.LytecConnector.CreatePin(LYTEC_KEY, "system", "9999"));
            UserInfo1 info = Connector.LytecConnector.AuthenticateUserPIN(LYTEC_KEY, "system", "9999");
            Assert.NotNull(info);
            if (info != null)
            {
                // Username must exist
                Assert.IsNotNullOrEmpty(info.UserName);

                // Name must exist
                Assert.IsNotNullOrEmpty(info.Name);
            }
            Assert.True(Connector.LytecConnector.CreatePin(LYTEC_KEY, "system", "1212"));
        }

        /// <summary>
        /// Testing with 'blank' provider (none specified)
        /// </summary>
        [Test]
        public void GetAppointments_2012()
        {
            DateTime dtStart = new DateTime(2012, 01, 01, 0, 0, 0);
            DateTime dtEnd = new DateTime(2012, 12, 31, 23, 59, 59);
            ProviderInfo1 info = new ProviderInfo1();
            info.UserId = "";

            AppointmentInfo1[] appointments = Connector.LytecConnector.GetAppointments(LYTEC_KEY, new ProviderInfo1[] { info }, null, dtStart, dtEnd);
            Assert.NotNull(appointments);
            if (appointments != null)
            {
                Assert.True(appointments.Length > 0);
                if (appointments.Length > 0)
                {
                    foreach (AppointmentInfo1 appt in appointments)
                    {
                        // Appt ID must be valid
                        Assert.True(appt.Id > 0);

                        // Appt Date must be valid
                        Assert.True(appt.StartDateTime.Year == 2012);
                    }
                }
            }
        }

        /// <summary>
        /// Testing with 'JM' provider (specified)
        /// </summary>
        [Test]
        public void GetAppointments_2012_DDL()
        {
            DateTime dtStart = new DateTime(2012, 01, 01, 0, 0, 0);
            DateTime dtEnd = new DateTime(2012, 12, 31, 23, 59, 59);
            ProviderInfo1 info = new ProviderInfo1();
            info.UserId = "DDL";

            AppointmentInfo1[] appointments = Connector.LytecConnector.GetAppointments(LYTEC_KEY, new ProviderInfo1[] { info }, null, dtStart, dtEnd);
            Assert.NotNull(appointments);
            if (appointments != null)
            {
                Assert.True(appointments.Length > 0);
                if (appointments.Length > 0)
                {
                    foreach (AppointmentInfo1 appt in appointments)
                    {
                        // Appt ID must be valid
                        Assert.True(appt.Id > 0);

                        // Appt Date must be valid
                        Assert.True(appt.StartDateTime.Year == 2012);

                        // Provider must either be JM or blank
                        Assert.True(appt.ProviderCode == "DDL" || appt.ProviderCode == "");
                    }
                }
            }
        }

        /// <summary>
        /// Testing with 'blank' provider (none specified)
        /// </summary>
        [Test]
        public void GetAppointments_2013()
        {
            DateTime dtStart = new DateTime(2013, 01, 01, 0, 0, 0);
            DateTime dtEnd = new DateTime(2013, 12, 31, 23, 59, 59);
            ProviderInfo1 info = new ProviderInfo1();
            info.UserId = "";

            AppointmentInfo1[] appointments = Connector.LytecConnector.GetAppointments(LYTEC_KEY, new ProviderInfo1[] { info }, null, dtStart, dtEnd);
            Assert.NotNull(appointments);
            if (appointments != null)
            {
                Assert.True(appointments.Length > 0);
                if (appointments.Length > 0)
                {
                    foreach (AppointmentInfo1 appt in appointments)
                    {
                        // Appt ID must be valid
                        Assert.True(appt.Id > 0);

                        // Appt Date must be valid
                        Assert.True(appt.StartDateTime.Year == 2013);
                    }
                }
            }
        }

        /// <summary>
        /// Testing with 'JM' provider (specified)
        /// </summary>
        [Test]
        public void GetAppointments_2013_DDL()
        {
            DateTime dtStart = new DateTime(2013, 01, 01, 0, 0, 0);
            DateTime dtEnd = new DateTime(2013, 12, 31, 23, 59, 59);
            ProviderInfo1 info = new ProviderInfo1();
            info.UserId = "DDL";

            AppointmentInfo1[] appointments = Connector.LytecConnector.GetAppointments(LYTEC_KEY, new ProviderInfo1[] { info }, null, dtStart, dtEnd);
            Assert.NotNull(appointments);
            if (appointments != null)
            {
                Assert.True(appointments.Length > 0);
                if (appointments.Length > 0)
                {
                    foreach (AppointmentInfo1 appt in appointments)
                    {
                        // Appt ID must be valid
                        Assert.True(appt.Id > 0);

                        // Appt Date must be valid
                        Assert.True(appt.StartDateTime.Year == 2013);

                        // Provider must either be JM or blank
                        Assert.True(appt.ProviderCode == "DDL" || appt.ProviderCode == "");
                    }
                }
            }
        }

        [Test]
        public void GetAppointmentDetail_1()
        {
            AppointmentDetail1 detail = Connector.LytecConnector.GetAppointmentDetail(LYTEC_KEY, 1, true);
            Assert.NotNull(detail);
            if (detail != null)
            {
                Assert.NotNull(detail.PatientDetail);
                if (detail.PatientDetail != null)
                {
                    Assert.IsNotNullOrEmpty(detail.PatientDetail.Patient.ChartId);
                    Assert.IsTrue(detail.PatientDetail.Patient.ChartId == "SMITH10000");
                }
            }
        }

        [Test]
        public void GetAppointmentDetail_2()
        {
            AppointmentDetail1 detail = Connector.LytecConnector.GetAppointmentDetail(LYTEC_KEY, 2, true);
            Assert.NotNull(detail);
            if (detail != null)
            {
                Assert.NotNull(detail.PatientDetail);
                if (detail.PatientDetail != null)
                {
                    Assert.IsNotNullOrEmpty(detail.PatientDetail.Patient.ChartId);
                    Assert.IsTrue(detail.PatientDetail.Patient.ChartId == "SMITH10001");
                }
            }
        }

        [Test]
        public void GetPatientDetail_Steve()
        {
            PatientDetail1 detail = Connector.LytecConnector.GetPatientDetail(LYTEC_KEY, null, "0000000100", true);
            Assert.NotNull(detail);
            if (detail != null)
            {
                Assert.IsNotNullOrEmpty(detail.Patient.ChartId);
                Assert.IsTrue(detail.Patient.ChartId == "0000000100");
                Assert.IsTrue(detail.Patient.FirstName == "Steve");
                Assert.IsTrue(detail.Patient.LastName == "Lyashtuck");
            }
        }

        [Test]
        public void PostIntoPendingTransaction_1()
        {
            BillingPost1 bill = new BillingPost1();
            //bill.BirthDate = DateTime.MinValue;
            bill.BirthDate = new DateTime(1974, 8, 13);
            bill.ChartID = "ALDERM0000";
            bill.DateFrom = DateTime.Now;
            bill.PatientFirstName = "Robert";
            bill.PatientLastName = "Aldermend";
            bill.PatientSocialSecurity = "648-54-1679";
            //bill.PatientSocialSecurity = "";
            bill.ProviderID = "DDL";
            bill.BillingDetails = new BillingDetail1[5] { new BillingDetail1(), new BillingDetail1(), new BillingDetail1(), new BillingDetail1(), new BillingDetail1() };
            int nLength = bill.BillingDetails.Length;
            bill.BillingDetails[0].Units = 2;
            bill.BillingDetails[0].DiagnosisCodes = new string[] { "728.4" };
            bill.BillingDetails[0].ProcedureCode = "11426";
            bill.BillingDetails[1].BillingNote = "Doris Day";
            bill.BillingDetails[2].BillingNote = "Doris Day";
            bill.BillingDetails[3].Units = 4;
            bill.BillingDetails[3].DiagnosisCodes = new string[] { "728.4" };
            bill.BillingDetails[3].ProcedureCode = "11426";
            bill.BillingDetails[4].Units = 4;
            bill.BillingDetails[4].DiagnosisCodes = new string[] { "728.4" };
            bill.BillingDetails[4].ProcedureCode = "11426";
            bool bSuccess = Connector.LytecConnector.PostBilling(LYTEC_KEY, "system", bill);
            Assert.IsTrue(bSuccess);
        }
    }
}
