using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Runtime.CompilerServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using sxlib.Static;
namespace sxlib.Specialized
{
    public class SxLibBase
    {
        protected SxLibBase(string synapseDir)
        {
            this.SynapseDir = synapseDir;
            if (!this.SynapseDir.EndsWith("synapse"))
            {
                string appendedDir = this.SynapseDir + "synapse";
                this.SynapseDir = appendedDir;
            }
        }
        protected virtual void VerifyWebsite()
        {
        }
        protected virtual string VerifyWebsiteWithVersion()
        {
            return string.Empty;
        }
        protected event SynLoadDelegate LoadEventInternal
        {
            add
            {
                SynLoadDelegate synLoadDelegate = this.LoadEvent;
                SynLoadDelegate synLoadDelegate2;
                do
                {
                    synLoadDelegate2 = synLoadDelegate;
                    SynLoadDelegate value2 = (SynLoadDelegate)Delegate.Combine(synLoadDelegate2, value);
                    synLoadDelegate = Interlocked.CompareExchange<SynLoadDelegate>(ref this.LoadEvent, value2, synLoadDelegate2);
                }
                while (synLoadDelegate != synLoadDelegate2);
            }
            remove
            {
                SynLoadDelegate synLoadDelegate = this.LoadEvent;
                SynLoadDelegate synLoadDelegate2;
                do
                {
                    synLoadDelegate2 = synLoadDelegate;
                    SynLoadDelegate value2 = (SynLoadDelegate)Delegate.Remove(synLoadDelegate2, value);
                    synLoadDelegate = Interlocked.CompareExchange<SynLoadDelegate>(ref this.LoadEvent, value2, synLoadDelegate2);
                }
                while (synLoadDelegate != synLoadDelegate2);
            }
        }
        protected event SynAttachDelegate AttachEventInternal
        {
            add
            {
                SynAttachDelegate synAttachDelegate = this.AttachEvent;
                SynAttachDelegate synAttachDelegate2;
                do
                {
                    synAttachDelegate2 = synAttachDelegate;
                    SynAttachDelegate value2 = (SynAttachDelegate)Delegate.Combine(synAttachDelegate2, value);
                    synAttachDelegate = Interlocked.CompareExchange<SynAttachDelegate>(ref this.AttachEvent, value2, synAttachDelegate2);
                }
                while (synAttachDelegate != synAttachDelegate2);
            }
            
            remove
            
            {
                SynAttachDelegate synAttachDelegate = this.AttachEvent;
                SynAttachDelegate synAttachDelegate2;
                do
                {
                    synAttachDelegate2 = synAttachDelegate;
                    SynAttachDelegate value2 = (SynAttachDelegate)Delegate.Remove(synAttachDelegate2, value);
                    synAttachDelegate = Interlocked.CompareExchange<SynAttachDelegate>(ref this.AttachEvent, value2, synAttachDelegate2);
                }
                while (synAttachDelegate != synAttachDelegate2);
            }
        }
        protected event SynScriptHubDelegate HubEventInternal
        {
            add
            {
                SynScriptHubDelegate synScriptHubDelegate = this.HubEvent;
                SynScriptHubDelegate synScriptHubDelegate2;
                do
                {
                    synScriptHubDelegate2 = synScriptHubDelegate;
                    SynScriptHubDelegate value2 = (SynScriptHubDelegate)Delegate.Combine(synScriptHubDelegate2, value);
                    synScriptHubDelegate = Interlocked.CompareExchange<SynScriptHubDelegate>(ref this.HubEvent, value2, synScriptHubDelegate2);
                }
                while (synScriptHubDelegate != synScriptHubDelegate2)  }
            remove
            {
                SynScriptHubDelegate synScriptHubDelegate = this.HubEvent;
                SynScriptHubDelegate synScriptHubDelegate2;
                do
                {
                    synScriptHubDelegate2 = synScriptHubDelegate;
                    SynScriptHubDelegate value2 = (SynScriptHubDelegate)Delegate.Remove(synScriptHubDelegate2, value);
                    synScriptHubDelegate = Interlocked.CompareExchange<SynScriptHubDelegate>(ref this.HubEvent, value2, synScriptHubDelegate2);
                }
                while (synScriptHubDelegate != synScriptHubDelegate2);
            }
        }
        protected bool _xmxIsInit;
        protected bool _xmxIsRegistered;
        protected SynConnection _synConnection;
        protected bool _synattached;
        protected bool _synLoaded;
        protected string SynapseDir;
        protected string Synpipe;
        protected string Version;
        protected string FileDir;
        protected string FullPath;
        protected string _pipeName;
        protected bool IsReadon;
        protected bool _hasverified;
        protected bool _hasverifiedwithversion;
        protected bool _attachedandloaded;
        protected bool _synRegAsProtectedByDefault;
        protected bool _synAttachAsProtectedByDefault;
        protected bool _synRegAsReadOnByDefault;
        protected bool _synAttachAsReadOnByDefault;
        protected bool _synRegAutoExecute;
        protected bool _synAttachAutoExecute;
        protected bool _threadScriptHub;
        protected bool _threadEnv;
        protected Thread _threadScriptHubA;
        protected Thread _threadEnvA;
        protected string _scriptHubScript;
        protected string _scriptHubAuthor;
        protected bool _enviroStarted;
        protected bool _enviroLoaded;
        protected bool _enviroAttached;
        protected bool _enviroClosed;
        protected Dictionary<string, string> _enviroVals;
        protected bool _synAttached
        {
            get
            {
                return this._synattached;
            }
            set
            {
                if (value)
                {
                    this._synattached = true;
                    if (this._attachedandloaded)
                    {
                        this.AttachEvent?.Invoke();
                    }
                }
                else
                {
                    this._synattached = false;
                }
            }
        }
        protected bool _synLoadedSet
        {
            get
            {
                return this._synLoaded;
            }
            set
            {
                if (value)
                {
                    this._synLoaded = true;
                    if (this._attachedandloaded)
                    {
                        this.LoadEvent?.Invoke();
                    }
                }
                else
                {
                    this._synLoaded = false;
                }
            }
        }
        protected SynConnection SynConnection
        {
            get
            {
                return this._synConnection;
            }
        }
        protected virtual bool SynAPILoad()
        {
            if (!this._hasverified)
            {
                this.VerifyWebsite();
                this._hasverified = true;
            }
            if (!this._hasverifiedwithversion)
            {
                this.Version = this.VerifyWebsiteWithVersion();
                this._hasverifiedwithversion = true;
            }
            if (!this._xmxIsRegistered)
            {
                if (!File.Exists(this.FullPath))
                {
                    return false;
                }
                this._xmxIsRegistered = true;
            }
            if (!this._xmxIsInit)
            {
                if (!this._synRegAsProtectedByDefault)
                {
                    if (!SynRegApi.SetProtected())
                    {
                        return false;
                    }
                }
                if (!this._synRegAsReadOnByDefault)
                {
                    if (!SynRegApi.SetReadon())
                    {
                        return false;
                    }
                }
                if (!SynRegApi.SetAutorun())
                {
                    return false;
                }
                this._xmxIsInit = true;
            }
            return true;
        }
        protected virtual bool SynAPIAttach()
        {
            if (this._synattached)
            {
                return true;
            }
            if (!this._synAttachAsProtectedByDefault)
            {
                if (!SynAPI.IsProtected())
                {
                    return false;
                }
            }
            if (!this._synAttachAsReadOnByDefault)
            {
                if (!SynAPI.IsReadon())
                {
                    return false;
                }
            }
            if (!this._synAttachAutoExecute)
            {
                if (!SynAPI.SetAutoExecute())
                {
                    return false;
                }
            }
            this._synattached = true;
            return true;
        }
        protected void SynAPIDetach()
        {
            if (!this._synattached)
            {
                return;
            }
            this._synattached = false;
        }
        protected void SynAPIClose()
        {
            if (!this._synattached)
            {
                return;
            }
            this._synattached = false;
            this._synConnection.Close();
        }
        public virtual bool Load(string pipeName, string fileDir)
        {
            this._pipeName = pipeName;
            this.FileDir = fileDir;
            this.FullPath = Path.Combine(this.FileDir, this._pipeName);
            if (!this.SynAPILoad())
            {
                return false;
            }
            this._synConnection = new SynConnection(this._pipeName, SynConnectionMode.Attached, SynConnectionType.Default);
            this._synConnection.Attached += this.SynAttached;
            this._synConnection.Loaded += this.SynLoaded;
            if (!this._synConnection.Open())
            {
                return false;
            }
            this._attachedandloaded = true;
            if (this._synattached && this._synLoaded)
            {
                this.InitHub();
                return true;
            }
            return false;
        }
        protected void SynAttached(SynConnection conn)
        {
            this._synAttached = true;
            if (this._synLoaded)
            {
                this.AttachEvent?.Invoke();
            }
        }
        protected void SynLoaded(SynConnection conn)
        {
            this._synLoadedSet = true;
            if (this._synattached)
            {
                this.LoadEvent?.Invoke();
            }
        }
        public virtual void InitHub()
        {
            if (this._threadScriptHub)
            {
                this._threadScriptHubA = new Thread(new ThreadStart(this.ScriptHubEventLoop));
                this._threadScriptHubA.Start();
            }
            if (this._threadEnv)
            {
                this._threadEnvA = new Thread(new ThreadStart(this.EnvEventLoop));
                this._threadEnvA.Start();
            }
        }
        protected virtual void ScriptHubEventLoop()
        {
            while (this._synattached && this._synLoaded)
            {
                this.HubEvent?.Invoke();
                Thread.Sleep(100);
            }
        }
        protected virtual void EnvEventLoop()
        {
            while (this._enviroLoaded && this._enviroAttached && !this._enviroClosed)
            {
                this.EnvEvent?.Invoke();
                Thread.Sleep(100);
            }
        }
        public virtual bool AddEnvValue(string key, string value)
        {
            if (this._enviroClosed || this._enviroAttached)
            {
                return false;
            }
            if (this._enviroVals == null)
            {
                this._enviroVals = new Dictionary<string, string>();
            }
            this._enviroVals[key] = value;
            return true;
        }
        public virtual bool RemoveEnvValue(string key)
        {
            if (this._enviroClosed || this._enviroAttached)
            {
                return false;
            }
            if (this._enviroVals == null)
            {
                return false;
            }
            return this._enviroVals.Remove(key);
        }
        public virtual void Close()
        {
            this._enviroClosed = true;
            this._synattached = false;
            this._synConnection.Close();
        }
    }
}