using System;
using System.Collections.Generic;
using System.Deployment.Application;
using System.IO;
using System.Linq;
using System.Reflection;
using Cocoa.Settings.UI;
using Microsoft.Win32;

namespace Cocoa.Settings
{
    public interface ICocoaRegistryEditor
    {
        void UpdateExtensionRegistryKeys(IEnumerable<ExtensionViewModel> extensions);
        IEnumerable<ExtensionViewModel> GetExtensionsFromRegistry();
    }

    public class CocoaRegistryEditor : ICocoaRegistryEditor
    {
        private const string CocoaKeyName = "Cocoa.md";

        public void UpdateExtensionRegistryKeys(IEnumerable<ExtensionViewModel> extensions)
        {
            var exePath = Assembly.GetEntryAssembly().Location;

            var software = Registry.CurrentUser.OpenSubKey("Software");
            if (software == null) return;
            using (var classesKey = software.OpenSubKey("Classes", true))
            {
                if (classesKey == null) return;
                foreach (var ext in extensions)
                {
                    using (var extensionKey = classesKey.CreateSubKey(ext.Extension))
                    {
                        if (extensionKey != null)
                            extensionKey.SetValue("", ext.Enabled ? CocoaKeyName : "");
                    }
                }

                using (var CocoaKey = classesKey.CreateSubKey(CocoaKeyName))
                {
                    if (CocoaKey == null) return;
                    using (var defaultIconKey = CocoaKey.CreateSubKey("DefaultIcon"))
                    {
                        if (defaultIconKey != null)
                            defaultIconKey.SetValue("", Path.Combine(Constants.IconDir, Constants.Icons[0]));
                    }

                    using (var shellKey = CocoaKey.CreateSubKey("shell"))
                    {
                        if (shellKey == null) return;
                        using (var openKey = shellKey.CreateSubKey("open"))
                        {
                            if (openKey == null) return;
                            using (var commandKey = openKey.CreateSubKey("command"))
                            {
                                if (commandKey != null)
                                {
                                    if (ApplicationDeployment.IsNetworkDeployed)
                                    {
                                        var path =
                                            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Programs),
                                                "Code52");

                                        var files = Directory.GetFiles(path, "*.appref-ms");
                                        if (files.Length == 0)
                                            commandKey.SetValue("", "\"" + exePath + "\" \"%1\"");
                                        else
                                        {
                                            commandKey.SetValue("", "cmd /c \"\"" + files[0] + "\" \"%1\"\"");
                                        }
                                    }
                                    else
                                    {
                                        commandKey.SetValue("", "\"" + exePath + "\" \"%1\"");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        public IEnumerable<ExtensionViewModel> GetExtensionsFromRegistry()
        {
            IEnumerable<ExtensionViewModel> extensions = new ExtensionViewModel[0];
            var softwareKey = Registry.CurrentUser.OpenSubKey("Software");
            if (softwareKey != null)
            {
                using (var key = softwareKey.OpenSubKey("Classes"))
                {
                    if (key != null)
                    {
                        extensions = Constants.MDDefaultExtensions
                                              .Select(s =>
                                              {

                                                  var openSubKey = key.OpenSubKey(s);
                                                  return new ExtensionViewModel(s, Enabled(s, key, openSubKey));
                                              })
                                              .Where(e => e != null)
                                              .ToArray();
                    }
                }
            }
            return extensions;
        }

        private bool Enabled(string s, RegistryKey key, RegistryKey openSubKey)
        {
            var defaultNameValue = openSubKey == null ? null : openSubKey.GetValue(null);
            var defaultNameValueAsString = defaultNameValue == null ? null : defaultNameValue.ToString();
            return openSubKey != null &&
                   (key.GetSubKeyNames().Contains(s) &&
                    !string.IsNullOrEmpty(defaultNameValueAsString));
        }
    }
}