using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;

namespace NtpServerManager
{
    public partial class FormMain : Form
    {
        private const string _TimeSyncServerPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers";
        private const string _TimeSyncServerValueName = "1";

        private const string _InternetTimeServerPath = @"SYSTEM\CurrentControlSet\Services\W32Time\Parameters";
        private const string _InternetTimeServerValueName = "NtpServer";


        public FormMain()
        {
            InitializeComponent();
            GetTimeSyncServer();
            GetInternetTimeServer();
        }

        private void GetTimeSyncServer()
        {
            string valueName = "1";
            string keyName = Path.Combine("HKEY_LOCAL_MACHINE", _TimeSyncServerPath);
            object value = Registry.GetValue(keyName, null, null);
            if (value != null)
                valueName = value.ToString();

            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_TimeSyncServerPath, true))
                {
                    if (key != null)
                        lb_TimeSyncServer.Text = key.GetValue(valueName).ToString();
                    else
                        throw new Exception("레지스트리 키를 열 수 없습니다.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("인터넷 시간 자동 동기화 서버 설정 > {0}", ex.Message), "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void GetInternetTimeServer()
        {
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_InternetTimeServerPath, true))
                {
                    if (key != null)
                        lb_InternetTimeServer.Text = key.GetValue(_InternetTimeServerValueName).ToString();
                    else
                        throw new Exception("레지스트리 키를 열 수 없습니다.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("인터넷 시간 서버 설정 > {0}", ex.Message), "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SetTimeSyncServer(string ntpServerAddress)
        {
            string keyName = Path.Combine("HKEY_LOCAL_MACHINE", _TimeSyncServerPath);
            object value = Registry.GetValue(keyName, null, null);
            if (value != null && value.ToString() != _TimeSyncServerValueName)
                Registry.SetValue(keyName, null, _TimeSyncServerValueName);
                
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_TimeSyncServerPath, true))
                {
                    if (key != null)
                        key.SetValue(_TimeSyncServerValueName, ntpServerAddress);
                    else
                        throw new Exception("레지스트리 키를 열 수 없습니다.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("인터넷 시간 자동 동기화 서버 설정 > {0}", ex.Message), "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SetInternetTimeServer(string ntpServerAddress)
        {
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_InternetTimeServerPath, true))
                {
                    if (key != null)
                    {
                        key.SetValue(_InternetTimeServerValueName, ntpServerAddress);
                        key.SetValue("Type", "NTP");
                    }
                        
                    else
                        throw new Exception("레지스트리 키를 열 수 없습니다.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("인터넷 시간 서버 설정 > {0}", ex.Message), "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SynchronizeTimeWithNtpServer(string ntpServerAddress)
        {
            // w32tm 명령어 실행
            string command = $"/c w32tm /config /manualpeerlist:\"{ntpServerAddress}\" /syncfromflags:manual /reliable:YES /update";
            ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", command);
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            psi.CreateNoWindow = true;
            psi.UseShellExecute = false;
            psi.RedirectStandardOutput = true;

            using (Process process = new Process())
            {
                process.StartInfo = psi;
                process.Start();
                process.WaitForExit();

                // w32tm 결과 출력
                MessageBox.Show(string.Format("인터넷 시간 동기화 > {0}", process.StandardOutput.ReadToEnd()));
            }
        }

        private void btn_Apply_Click(object sender, EventArgs e)
        {
            string ntpServerIP = string.Format("{0}.{1}.{2}.{3}"
                , nud_IPPart1.Value.ToString()
                , nud_IPPart2.Value.ToString()
                , nud_IPPart3.Value.ToString()
                , nud_IPPart4.Value.ToString());

            SetTimeSyncServer(ntpServerIP);
            SetInternetTimeServer(ntpServerIP);
            SynchronizeTimeWithNtpServer(ntpServerIP);

            GetTimeSyncServer();
            GetInternetTimeServer();
        }
    }
}
