using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using System.Data;
using IndianHealthService.BMXNet.Model;


namespace IndianHealthService.BMXNet.Tests
{

    /// <summary>
    /// BMX ADO SS^BMX TEST FILE^^~~~~~
    /// 
    /// </summary>
    /// 
    public class FieldTypesAndFieldConstraints : BmxValidUserTestSuite
    {


        private DataRow _testRow;

        public DataRow TestRow
        {
            get { return _testRow; }
            set { _testRow = value; }
        }
        private DataTable _testTable;

        public DataTable TestTable
        {
            get { return _testTable; }
            set { _testTable = value; }
        }

        public bool GenerateValidTestRow()
        {
       //     BMXNetScriptedBroker broker = new BMXNetScriptedBroker();
       //     broker.AddCall(
         //       @"{BMX}0007700062007BMX;;;;000470BMX ADO SS^000300140BMX TEST FILE00100060~~~~~",
           //     @"@@@meta@@@BMXIEN|90093.97|^90093.97|.001|N|15|BMXIEN|TRUE|TRUE|FALSE^90093.97|.01|T|30|NAME|FALSE|FALSE|FALSE^90093.97|.02|N|4|NUMBER|FALSE|FALSE|TRUE^90093.97|.03|D|21|DATE|FALSE|FALSE|TRUE^90093.97|.04|D|21|DATE TIME|FALSE|FALSE|TRUE^90093.97|.05|T|3|SET|FALSE|FALSE|TRUE^90093.97|.06|T|30|NAME R/O|TRUE|FALSE|TRUE^90093.97|.07|N|4|NUMBER R/O|TRUE|FALSE|TRUE^90093.97|.08|D|21|DATE R/O|TRUE|FALSE|TRUE^90093.97|.09|D|21|DATE TIME R/O|TRUE|FALSE|TRUE^90093.97|.1|T|3|SET R/O|TRUE|FALSE|TRUE^90093.97|.11|I|2|INTEGER|FALSE|FALSE|TRUE^90093.97|.12|I|2|INTEGER R/O|TRUE|FALSE|TRUE1^John^8^OCT 10, 1970^^^^^^^^^");

                //SMH: Table needs to be cleared at this point since it expects to have a clean slate
                //SMH: And here it is!
                DataTable table = this.RemoteSession.TableFromCommand(this.FetchTableString);

                foreach (DataRow each in table.Rows)
                {
                    each.Delete();
                }
                this.RemoteSession.SaveChanges(table);
                //end my changes

                table = this.RemoteSession.TableFromCommand(this.FetchTableString);
                DataRow row = table.NewRow();
                row["NAME"] = "John";
                row["DATE"] = new DateTime(1970, 10, 10);
                row["NUMBER"] = 8;
                row["NUMBER R/O"] = 9;
                table.Rows.Add(row);
                Assert.AreEqual(1, table.Rows.Count);

                Assert.IsTrue(this.RemoteSession.SaveChanges(table));

                this.TestTable = RemoteSession.TableFromCommand(this.FetchTableString);
                Assert.AreEqual(1, this.TestTable.Rows.Count);
                this.TestRow = this.TestTable.Rows[0];
                Assert.AreEqual(row["NAME"], "John");
                Assert.AreEqual(row["DATE"], new DateTime(1970, 10, 10));

                return true;
           
        }

        public bool RefetchTestRow()
        {
            try
            {
                this.TestTable = this.RemoteSession.TableFromCommand(this.FetchTableString);
                Assert.AreEqual(1, this.TestTable.Rows.Count);
                this.TestRow = this.TestTable.Rows[0];
                return true;
            }
            catch
            {
                return false;
            }
        }

        /*
              90093.97,.01  NAME                   0;1 FREE TEXT (Required) 
              INPUT TRANSFORM:  K:$L(X)>30!($L(X)<3)!'(X'?1P.E) X
              LAST EDITED:      JAN 16, 2008
              HELP-PROMPT:      Answer must be 3-30 characters in length.
              CROSS-REFERENCE:  90093.97^B
                                1)= S ^BMXTEST("B",$E(X,1,30),DA)=""
                                2)= K ^BMXTEST("B",$E(X,1,30),DA)
         */


        /*
            90093.97,.06  NUMBER                 0;6 NUMBER
              INPUT TRANSFORM:  K:+X'=X!(X>99)!(X<5)!(X?.E1"."2N.N) X
              LAST EDITED:      JAN 16, 2008
              HELP-PROMPT:      Type a Number between 5 and 99, 1 Decimal Digit*/
        [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void NumberMin()
        {
            this.GenerateValidTestRow();
            this.TestRow["Number"] = 0;
            this.RemoteSession.SaveChanges(this.TestTable);
        }

        [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void NumberMax()
        {
            this.GenerateValidTestRow();
            this.TestRow["Number"] = 120;
            this.RemoteSession.SaveChanges(this.TestTable);
        }

         [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void NumberTooManyDecimals()
        {
            this.GenerateValidTestRow();
            this.TestRow["Number"] = 120.1234;
            this.RemoteSession.SaveChanges(this.TestTable);
        }

        [Test]
        public void NumberDecimals()
        {
            this.GenerateValidTestRow();
            this.TestRow["NUMBER"] = 5.6;
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            Assert.AreEqual(this.TestRow["NUMBER"], 5.6);         
        }

        /*90093.97,.07  NUMBER R/O             0;7 NUMBER
 
              INPUT TRANSFORM:  K:+X'=X!(X>99)!(X<5)!(X?.E1"."1N.N) X
              LAST EDITED:      JAN 16, 2008
              HELP-PROMPT:      Type a Number between 5 and 99, 0 Decimal
                                Digits*/

        /// <summary>
        /// THIS WILL FAIL!!!! NOTHING IN THE BMX LIBRARY THROWS THIS EXCEPTION//SMH
        /// </summary>
        [Test]
        [ExpectedException(typeof(System.Data.ReadOnlyException))]
        public void UpdateReadOnlyNumber()
        {
            this.GenerateValidTestRow();
            this.TestRow["NUMBER R/O"] = 100;
        }


        [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void StringMinLength()
        {
            this.GenerateValidTestRow();
            this.TestRow["NAME"] = "John";
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            Assert.AreEqual(this.TestRow["NAME"], "John");         
            this.TestRow["NAME"] = "T";
            Assert.IsFalse(this.RemoteSession.SaveChanges(this.TestTable));
        }

        [Test]
        public void StringMinLengthNoSideEffect()
        {
            this.GenerateValidTestRow();
            this.TestRow["NAME"] = "John";
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            try
            {
                this.TestRow["NAME"] = "T";
                Assert.IsFalse(this.RemoteSession.SaveChanges(this.TestTable));
                Assert.IsTrue(false);
            }
            catch
            {
            }

            this.RefetchTestRow();
            Assert.AreEqual(this.TestRow["NAME"], "John");
        }

        [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void StringMaxLength()
        {
            this.GenerateValidTestRow();
            this.TestRow["NAME"] = "John";
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            Assert.AreEqual(this.TestRow["NAME"], "John");
            this.TestRow["NAME"] = "T1234567890123456789012345678901234567890";
            Assert.IsFalse(this.RemoteSession.SaveChanges(this.TestTable));
        }

        [Test]
        public void StringMaxLengthNoSideEffect()
        {
            this.GenerateValidTestRow();
            this.TestRow["NAME"] = "John";
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            try
            {
                this.TestRow["NAME"] = "T1234567890123456789012345678901234567890";
                Assert.IsFalse(this.RemoteSession.SaveChanges(this.TestTable));
                Assert.IsTrue(false);
            }
            catch
            {
            }

            this.RefetchTestRow();
            Assert.AreEqual(this.TestRow["NAME"], "John");                
        }

        /*90093.97,.03  DATE                   0;3 DATE
 
           INPUT TRANSFORM:  S %DT="EX" D ^%DT S X=Y K:Y<1 X
           LAST EDITED:      JAN 16, 2008*/
     [Test]
     public void SetDateAt0Second()
     {
         this.GenerateValidTestRow();
         this.TestRow["DATE"] = new DateTime(1950,1,1);
         Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

         this.RefetchTestRow();
         Assert.AreEqual(new DateTime(1950,1,1),(DateTime)this.TestRow["DATE"]);
     }


        [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void SetDateAtWithTime()
        {
            this.GenerateValidTestRow();
            this.TestRow["DATE"] = new DateTime(1950, 1, 1,10,30,30);
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            Assert.AreEqual(new DateTime(1950, 1, 1, 10, 30, 30), (DateTime)this.TestRow["DATE"]);
        }


        /*     
            90093.97,.04  DATE TIME              0;4 DATE 
           INPUT TRANSFORM:  S %DT="ETX" D ^%DT S X=Y K:Y<1 X
           LAST EDITED:      JAN 16, 2008*/
        [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void SetDateTimeAtWithTimeHavingSeconds()
        {
            this.GenerateValidTestRow();
            this.TestRow["DATE TIME"] = new DateTime(1950, 1, 1, 20, 30,1);
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));
         }

        /*90093.97,.05  DATE R/O               0;5 DATE
 
           INPUT TRANSFORM:  S %DT="EX" D ^%DT S X=Y K:Y<1 X*/

        [Test]
        public void SetDateTimeAtWithTime()
        {
            this.GenerateValidTestRow();
            this.TestRow["DATE TIME"] = new DateTime(1950, 1, 1, 20, 30, 0);
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            Assert.AreEqual(new DateTime(1950, 1, 1, 20, 30, 0), (DateTime)this.TestRow["DATE TIME"]);
        }


        /// <summary>
        /// THIS WILL FAIL!!!! NOTHING IN THE BMX LIBRARY THROWS THIS EXCEPTION//SMH
        /// </summary>
        [Test]
        [ExpectedException(typeof(System.Data.ReadOnlyException))]
        public void UpdateReadOnlyDate()
        {


            this.GenerateValidTestRow();
            this.TestRow["DATE R/O"] = new DateTime(1950, 1, 1);
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();
            String peek = this.TestRow["DATE R/O"].ToString();
            Assert.AreEqual(new DateTime(1950, 1, 1), (DateTime)this.TestRow["DATE R/O"]);
        }

        /*         * 93.97,.08  SET                    0;8 SET
 
                                '1' FOR YES;
                                '0' FOR NO;
              LAST EDITED:      JAN 16, 2008*/

        [Test]
        public void SetSetToCode()
        {
            this.GenerateValidTestRow();
            this.TestRow["SET"] = "YES";
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();

            Assert.AreEqual("YES", this.TestRow["SET"]);
        }
        [Test]
        public void SetSetToNull()
        {
            this.GenerateValidTestRow();
            this.TestRow["SET"] = "";
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();

            Assert.AreEqual("", this.TestRow["SET"]);
        }

        [Test]
        [ExpectedException(typeof(BMXNetException))]
        public void SetSetToInvalid()
        {
            this.GenerateValidTestRow();
            this.TestRow["SET"] = "MAYBE";
            Assert.IsTrue(this.RemoteSession.SaveChanges(this.TestTable));

            this.RefetchTestRow();

            Assert.AreEqual("MAYBE", this.TestRow["SET"]);
        }


        /*




        /*

 
90093.97,.09  SET R/O                0;9 SET
 
                                '1' FOR YES;
                                '0' FOR NO;
              LAST EDITED:      JAN 16, 2008
 
90093.97,.1   LOCATION               0;10 POINTER TO LOCATION FILE (#9999999.06
                                )
 */

 

    }
}
