//  Copyright (c) Microsoft Corporation.  All rights reserved.

namespace Microsoft.VisualStudio.TestTools.TestCaseMigrator
{
    using System.IO;
    using System.Xml;

    /// <summary>
    /// Wizard Part for Loading Settings Files
    /// </summary>
    internal class SettingsFilePart : BaseWizardPart
    {
        #region Fields

        /// <summary>
        /// Member Varaibles for Data binding
        /// </summary>
        private bool m_loadSettings;
        private string m_settingsFilePath;

        #endregion

        #region Constants
        
        private const string XMLExtension = ".xml";
        
        #endregion

        #region Constructor

        /// <summary>
        /// Constructor
        /// </summary>
        public SettingsFilePart()
        {
            Header = Resources.MappingsFile_Header;
            Description = Resources.MappingsFile_Description;
            CanBack = true;
            CanNext = true;
            CanFinish = false;
            WizardPage = WizardPage.SettingsFile;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Is settings File To be loaded
        /// </summary>
        public bool LoadSettings
        {
            get
            {
                return m_loadSettings;
            }
            set
            {
                m_loadSettings = value;
                EvaluateCanFinish();
                NotifyPropertyChanged("LoadSettings");
            }
        }

        /// <summary>
        /// File Path of the Settings File
        /// </summary>
        public string SettingsFilePath
        {
            get
            {
                return m_settingsFilePath;
            }
            set
            {
                m_settingsFilePath = value;
                EvaluateCanFinish();
                NotifyPropertyChanged("SettingsFilePath");
            }
        }

        #endregion

        #region public methods

        /// <summary>
        /// Resets the Settings Wizard Part to start from blank settings File
        /// </summary>
        public override void Reset()
        {
            LoadSettings = false;
            SettingsFilePath = m_wizardInfo.InputSettingsFilePath;
            m_wizardInfo.InputSettingsFilePath = string.Empty;
            m_wizardInfo.Migrator.SourceNameToFieldMapping = null;
        }

        /// <summary>
        /// Updates the Wizard Info and Loads Settings if Settings File is specified
        /// </summary>
        /// <returns></returns>
        public override bool UpdateWizardPart()
        {
            // If Wizard Part State is not valid return false
            if (!ValidatePartState())
            {
                return false;
            }

            try
            {
                // Load Settings if Settings File is specified and it is changed from last time
                if (LoadSettings)
                {
                    if (SettingsFilePath != m_wizardInfo.InputSettingsFilePath)
                    {
                        m_wizardInfo.LoadSettings(SettingsFilePath);
                        m_wizardInfo.InputSettingsFilePath = SettingsFilePath;
                    }
                }
                // else just updates the Input Settings FilePath in WizardInfo
                else if (!string.IsNullOrEmpty(m_wizardInfo.InputSettingsFilePath))
                {
                    m_wizardInfo.InputSettingsFilePath = null;
                    m_wizardInfo.DataSourceParser.ParseDataSourceFieldNames();
                    m_wizardInfo.Migrator.SourceNameToFieldMapping = null;
                }
                m_prerequisite.Save();
            }
            catch (XmlException)
            {
                m_wizardInfo.ProgressPart = null;
                ErrorArgs.Title = Resources.InputSettingsFileError;
                ErrorArgs.LikelyCause = Resources.InputSettingsFileErrorLikelyCause;
                ErrorArgs.PotentialSolution = Resources.InputSettingsFileErrorPotentialSolution;
                return false;
            }
            catch (TestCaseMigratorException te)
            {
                m_wizardInfo.ProgressPart = null;
                ErrorArgs = te.Args;
                return false;
            }
            return true;
        }

        #endregion

        #region protected/private methods

        /// <summary>
        /// We can initialize it if Data Source and Server connection is provided
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        protected override bool CanInitializeWizardPage(WizardInfo info)
        {
            string title = null;
            string likelyCause = null;
            string potentialSolution = null;
            m_canShow = true;

            if (info.DataSourceParser == null)
            {
                m_canShow = false;
                title = Resources.SettingsFilePart_CantShowTitle;
                likelyCause = Resources.DataSourceNotEnteredErrorLikelyCause;
                potentialSolution = Resources.DataSourceNotEnteredErrorPotentialSolution;
            }
            else if (info.WorkItemGenerator == null || info.WorkItemGenerator.TfsNameToFieldMapping == null || info.WorkItemGenerator.TfsNameToFieldMapping.Count == 0)
            {
                m_canShow = false;
                title = Resources.SettingsFilePart_CantShowTitle;
                likelyCause = Resources.ServerNotSpecifiedErrorLikelyCause;
                potentialSolution = Resources.ServerNotSpecifiedErrorPotentialSolution;
            }
            if (!m_canShow)
            {
                ErrorArgs.Title = title;
                ErrorArgs.LikelyCause = likelyCause;
                ErrorArgs.PotentialSolution = potentialSolution;
            }
            return m_canShow;
        }

        /// <summary>
        /// Initialization is required if there is any change in Data Source or Server Connection
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        protected override bool IsInitializationRequired(WizardInfo state)
        {
            if (m_wizardInfo == null || m_prerequisite.IsDataSourceChanged() || m_prerequisite.IsServerConnectionChanged())
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Validates part state for valid setting File
        /// </summary>
        /// <returns></returns>
        protected override bool ValidatePartState()
        {
            // If Setting File is Not Valid XML file return false
            if (LoadSettings && !CanFinish)
            {
                ErrorArgs.Title = Resources.InputSettingsFileError;
                ErrorArgs.LikelyCause = Resources.InputSettingsFileErrorLikelyCause;
                ErrorArgs.PotentialSolution = Resources.InputSettingsFileErrorPotentialSolution;
                return false;
            }
            if (m_wizardInfo == null)
            {
                ErrorArgs.Title = "Unexpected Action";
                return false;
            }
            if (m_wizardInfo.ProgressPart != null)
            {
                ErrorArgs.Title = "Action is not possible";
                ErrorArgs.LikelyCause = "Could not restart migration as migration is already in progress";
                ErrorArgs.PotentialSolution = "Please cancel the current migration or wait for its completion";
                return false;
            }
            return true;
        }

        /// <summary>
        /// Checks whether Finish button can be enabled or not based on Input Mapping file is valid or not.
        /// </summary>
        private void EvaluateCanFinish()
        {
            if (LoadSettings && Path.GetExtension(SettingsFilePath) == XMLExtension && File.Exists(SettingsFilePath))
            {
                CanFinish = true;
            }
            else
            {
                CanFinish = false;
            }
        }
        
        #endregion
    }
}
