// <copyright file="FinancialCardTrackTwo.cs" company="Scriptel Corporation">
//      Copyright 2014 - Scriptel Corporation
// </copyright>
namespace EasyScriptAPI
{
    using System;
    using System.Text;
    using System.Text.RegularExpressions;

    /// <summary>
    /// This class represents the second track of a financial card
    /// </summary>
    public class FinancialCardTrackTwo
    {
        /// <summary>
        /// account number
        /// </summary>
        private string accountNumber;
 
        /// <summary>
        /// card expiration date
        /// </summary>
        private DateTime expiration;
 
        /// <summary>
        /// service code
        /// </summary>
        private string serviceCode;

        /// <summary>
        /// discretionary data
        /// </summary>
        private string discretionaryData;

        /// <summary>
        /// This method attempts to parse track two out the raw track string.
        /// </summary>
        /// <param name="trackData">Track data to parse</param>
        /// <returns>FinancialCardTrackTwo data if data found, null otherwise.</returns>
        public static FinancialCardTrackTwo Parse(string trackData)
        {
            Regex regex = new Regex(".*;(\\d{1,19})=(\\d{2})(\\d{2})(\\d{3})([A-Za-z 0-9]*)\\?.*");
            Match m = regex.Match(trackData);
            if (m.Success)
            {
                FinancialCardTrackTwo track = new FinancialCardTrackTwo();
                track.SetAccountNumber(m.Groups[1].Value);
                track.SetServiceCode(m.Groups[4].Value);
                track.SetDiscretionaryData(m.Groups[5].Value);

                int year = int.Parse(m.Groups[2].Value) + 2000;
                int month = int.Parse(m.Groups[3].Value);

                DateTime thisMonth = new DateTime(year, month, 1, 0, 0, 0, 0);
                DateTime nextMonth = thisMonth.AddMonths(1);
                track.SetExpiration(nextMonth.AddMilliseconds(-1));
            
                return track;
            }

            return null;
        }

        /// <summary>
        /// Returns this object as a human readable string
        /// </summary>
        /// <returns>human readable string of this object</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            string ln = Environment.NewLine;
            sb.Append("Financial Card - Track Two:").Append(ln);
            sb.Append("    Account Number: ").Append(this.accountNumber).Append(ln);
            sb.Append("        Expiration: ").Append(this.expiration).Append(ln);
            sb.Append("      Service Code: ").Append(this.serviceCode).Append(ln);
            sb.Append("Discretionary Data: ").Append(this.discretionaryData).Append(ln);
            return sb.ToString();
        }

        /// <summary>
        /// Gets the account number of the card in track two.
        /// </summary>
        /// <returns>account number</returns>
        public string GetAccountNumber()
        {
            return this.accountNumber;
        }

        /// <summary>
        /// Gets the expiration date of the card
        /// </summary>
        /// <returns>Expiration date of the card.</returns>
        public DateTime GetExpiration()
        {
            return this.expiration;
        }
        
        /// <summary>
        /// Gets the service code of the card
        /// </summary>
        /// <returns>Service code of the card.</returns>
        public string GetServiceCode()
        {
            return this.serviceCode;
        }
        
        /// <summary>
        /// Gets the discretionary data on the second track of the card.
        /// </summary>
        /// <returns>Discretionary data on the second track of the card.</returns>
        public string GetDiscretionaryData()
        {
            return this.discretionaryData;
        }

        /// <summary>
        /// Sets the account number of the card in track two
        /// </summary>
        /// <param name="accountNumber">account number</param>
        private void SetAccountNumber(string accountNumber)
        {
            this.accountNumber = accountNumber;
        }

        /// <summary>
        /// Sets the expiration date of the card
        /// </summary>
        /// <param name="expiration">Date the card expires</param>
        private void SetExpiration(DateTime expiration)
        {
            this.expiration = expiration;
        }

        /// <summary>
        /// Sets the service code on the card.
        /// </summary>
        /// <param name="serviceCode">Service code on the card.</param>
        private void SetServiceCode(string serviceCode)
        {
            this.serviceCode = serviceCode;
        }

        /// <summary>
        /// Sets the discretionary data on the second track of the card.
        /// </summary>
        /// <param name="discretionaryData">Discretionary data on the second track of the card.</param>
        private void SetDiscretionaryData(string discretionaryData)
        {
            this.discretionaryData = discretionaryData;
        }
    }
}
