using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;

namespace KarleyLibrary
{
    [SupportedOSPlatform("windows")]
    public class RegistryLibrary
    {
        public string Path { get; set; }
        public RegistryType Type { get; set; }

        public RegistryLibrary(string path, RegistryType type)
        {
            Path = path;
            Type = type;
        }

        #region object
        public object? Get(string key) => Get(Path, key, Type);

        public bool Exists(string key) => Exists(Path, key, Type);

        public void Write(string key, object value) => Write(Path, key, value, Type);        

        public void Delete(string key) => Delete(Path, key, Type);        
        #endregion


        #region static
        public static object? Get(string path, string key, RegistryType type)
        {
            RegistryKey? registryKey = TypeToKey(type).CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
            return registryKey.GetValue(key);
        }

        public static bool Exists(string path, string key, RegistryType type)
        {
            return TypeToKey(type).OpenSubKey(path)?.GetValue(key) != null;
        }

        public static void Write(string path, string key, object value, RegistryType type)
        {
            RegistryKey registryKey = TypeToKey(type).CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
            registryKey.SetValue(key, value);
        }

        public static void Delete(string path, string key, RegistryType type)
        {
            if (Exists(path, key, type))
            {
                RegistryKey registryKey = TypeToKey(type).CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
                registryKey.DeleteValue(key);
            }
        }

        #endregion

        private static RegistryKey TypeToKey(RegistryType type)
        {
            return type switch
            {
                RegistryType.CurrentUser => Registry.CurrentUser,
                RegistryType.LocalMachine => Registry.LocalMachine,
                RegistryType.ClassesRoot => Registry.ClassesRoot,
                RegistryType.CurrenConfig => Registry.CurrentConfig,
                RegistryType.PerformanceData => Registry.PerformanceData,
                RegistryType.Users => Registry.Users,
                _ => Registry.CurrentUser
            };
        }
    }

    public enum RegistryType
    {
        CurrentUser,
        LocalMachine,
        ClassesRoot,
        Users,
        PerformanceData,
        CurrenConfig
    }
}
