using System;
using System.Data.SqlClient;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Windows.Forms;
using AdvertisingProfitControlData;
using Microsoft.Win32;

namespace AdvertsingProfitControl
{
    public partial class FrmLoginForm : Form
    {
        public bool ConnectionSuccessful;

        public FrmLoginForm()
        {
            InitializeComponent();
            //Check to see if the backup folder exists.
            if (!Directory.Exists(Backup.DefaultBackupLocation))
            {
                Directory.CreateDirectory(Backup.DefaultBackupLocation);
                //Create it and set its permissions so SQL can write to it.
                //Reference: https://stackoverflow.com/questions/5298905/add-everyone-privilege-to-folder-using-c-net
                var sec = Directory.GetAccessControl(Backup.DefaultBackupLocation);
                // Using this instead of the "Everyone" string means we work on non-English systems.
                var everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
                sec.AddAccessRule(new FileSystemAccessRule(everyone, FileSystemRights.Modify | FileSystemRights.Synchronize, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
                Directory.SetAccessControl(Backup.DefaultBackupLocation, sec);
            }
            //Scan the registry for SQL server instances (not the recommended way).
            var registryView = Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32;
            using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView))
            {
                var instanceKey = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", false);
                if (instanceKey != null)
                {
                    foreach (var instanceName in instanceKey.GetValueNames())
                    {
                        serverNameComboBox.Items.Add(Environment.MachineName + @"\" + instanceName);
                    }
                }
            }
            //Set the default server
            serverNameComboBox.Text = Properties.Settings.Default.DefaultServer;
            authenticationTypeComboBox.SelectedIndex = 0;
            serverNameComboBox.TextChanged += ServerNameTextChanged;
        }

        private void ServerNameTextChanged(object sender, EventArgs e)
        {
            //Disable the connect button if the combo box's text is empty.
            connectButton.Enabled = serverNameComboBox.Text.Length != 0;
        }

        private void AttemptConnection(object sender, EventArgs e)
        {           
            var connectionString = "Data Source=" + serverNameComboBox.Text + ";Initial Catalog=AdvertisingProfitControl;Integrated Security=True;MultipleActiveResultSets=True;App=EntityFramework";
            try
            {
                //Test the connection string with a forced timeout of 2 seconds.
                using (var conn = new SqlConnection("Data Source=" + serverNameComboBox.Text + ";Integrated Security=True;MultipleActiveResultSets=True;App=EntityFramework;Connection Timeout=2"))
                {                   
                    conn.Open(); // throws if invalid
                    conn.Close();
                }
                Properties.Settings.Default.ConnectionString = connectionString;
                //Set the default server name.
                if (Properties.Settings.Default.DefaultServer != serverNameComboBox.Text)
                {
                    Properties.Settings.Default.DefaultServer = serverNameComboBox.Text;
                    Properties.Settings.Default.Save();
                }
                ConnectionSuccessful = true;
                //Try to initialize the database.
                var db = new AdvertisingProfitControlDbContext(connectionString);
                //Force the UI thread to draw the label's text so the user can see it.
                informationLabel.Text = @"Connection successful! Preparing main form...";
                informationLabel.Invalidate();
                informationLabel.Update();
                informationLabel.Refresh();
                db.Database.Initialize(false);            
                db.Database.Connection.Close();
                Close();
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message, @"Connection Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
                informationLabel.Text = @"Failed to connect to a database.";
            }
        }
    }
}
