using System;

using Cosmos.IL2CPU.API.Attribs;

namespace Cosmos.CPU.x86 {
    // Non hardware class, only used by core and hardware drivers for ports etc.
    public class Processor {
        // Amount of RAM in MB's.
        // needs to be static, as Heap needs it before we can instantiate objects
        [PlugMethod(PlugRequired = true)]
        public static uint GetAmountOfRAM() {
            throw new NotImplementedException();
        }

        // needs to be static, as Heap needs it before we can instantiate objects
        [PlugMethod(PlugRequired = true)]
        public static uint GetEndOfKernel() {
            throw new NotImplementedException();
        }

        [PlugMethod(PlugRequired = true)]
        public void UpdateIDT(bool aEnableInterruptsImmediately) {
            throw new NotImplementedException();
        }

        [PlugMethod(PlugRequired = true)]
        public void InitFloat() {
            throw new NotImplementedException();
        }

        [PlugMethod(PlugRequired = true)]
        public void InitSSE() {
            throw new NotImplementedException();
        }

        [PlugMethod(PlugRequired = true)]
        public static void ZeroFill(uint aStartAddress, uint aLength) {
            throw new NotImplementedException();
        }

        [PlugMethod(PlugRequired = true)]
        public void Halt() {
            throw new NotImplementedException();
        }

        public void Reboot() {
            // Disable all interrupts
            DisableInterrupts();

            var myPort = new IOPort(0x64);
            while ((myPort.Byte & 0x02) != 0) {
            }
            myPort.Byte = 0xFE;
            Halt(); // If it didn't work, Halt the Processor
        }

        private static void DoEnableInterrupts() {
            throw new NotImplementedException();
        }

        private static void DoDisableInterrupts() {
            throw new NotImplementedException();
        }

        [AsmMarker(AsmMarker.Type.Processor_IntsEnabled)]
        public static bool mInterruptsEnabled;

        public static void EnableInterrupts() {
            mInterruptsEnabled = true;
            DoEnableInterrupts();
        }

        /// <summary>
        /// Returns if the interrupts were actually enabled
        /// </summary>
        /// <returns></returns>
        public static bool DisableInterrupts() {
            DoDisableInterrupts();
            var xResult = mInterruptsEnabled;
            mInterruptsEnabled = false;
            return xResult;
        }
    }
}
