using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antmicro.Renode.Core;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.CPU;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Utilities;

namespace Antmicro.Renode.Debug
{
    public static class seL4Extensions
    {
        public static void CreateseL4(this RiscV32 @this)
        {
            EmulationManager.Instance.CurrentEmulation.ExternalsManager.AddExternal(new seL4(@this), "seL4");
        }
    }

    public class seL4 : IExternal
    {
        public seL4(RiscV32 cpu)
        {
            this.cpu = cpu;
            this.mapping = new Dictionary<ulong, string>();
            this.breakpoints = new Dictionary<string, SortedSet<ulong?>>();

            var handleUnknownSyscallAddress = bus.GetSymbolAddress("handleUnknownSyscall");
            this.cpu.AddHook(handleUnknownSyscallAddress, HandleUnknownSyscall);
            var idleThreadAddresss = bus.GetSymbolAddress("idle_thread");
            this.cpu.AddHook(idleThreadAddresss, Finalize);
        }

        public string CurrentThread()
        {
            var tcb = bus.ReadDoubleWord(this.ksCurThreadPhysAddress, context: cpu);
            if(!mapping.ContainsKey(tcb))
            {
                return "default";
            }
            return mapping[tcb];
        }

        public void WaitForThread(string threadName)
        {
            pendingThreadName = threadName;
        }

        public void SetBreakpoint(string threadName, ulong? address = null)
        {
            var realThreadName = mapping.Values.Where(thread => thread.Contains(threadName)).FirstOrDefault();
            if(String.IsNullOrEmpty(realThreadName))
            {
                this.Log(LogLevel.Warning, "No thread with name '{0}' found.", threadName);
                return;
            }

            if(!breakpoints.ContainsKey(realThreadName))
            {
                breakpoints.Add(realThreadName, new SortedSet<ulong?>());
            }

            if(!breakpoints[realThreadName].Add(address))
            {
                this.Log(LogLevel.Warning, "This breakpoint already exists.");
            }
        }

        public void RemoveBreakpoint(string threadName, ulong? address = null, bool removeAll = false)
        {
            var realThreadName = mapping.Values.Where(thread => thread.Contains(threadName)).FirstOrDefault();
            if(String.IsNullOrEmpty(realThreadName))
            {
                this.Log(LogLevel.Warning, "No thread with name '{0}' found.", threadName);
                return;
            }

            if(!breakpoints.ContainsKey(realThreadName))
            {
                return;
            }

            if(removeAll)
            {
                foreach(var addr in breakpoints[realThreadName])
                {
                    if(addr != null)
                    {
                        cpu.RemoveHook(addr.Value, HandleBreakpoint);
                    }
                }

                breakpoints.Remove(realThreadName);
            }
            else
            {
                if(breakpoints[realThreadName].Remove(address) && address != null)
                {
                    cpu.RemoveHook(address.Value, HandleBreakpoint);
                }
            }
        }

        public string[,] GetBreakpoints(string threadName = null)
        {
            var entries = breakpoints.SelectMany(t => t.Value, (thread, address) => new { Thread = thread.Key, Address = address });
            if(threadName != null)
            {
                entries = entries.Where(x => x.Thread.Contains(threadName));
            }
            var table = new Table().AddRow("Thread", "Address");
            table.AddRows(entries, x => x.Thread, x => x.Address == null ? "null" : "0x{0:X}".FormatWith(x.Address));
            return table.ToArray();
        }

        private void HandleUnknownSyscall(ICpuSupportingGdb _cpu, ulong address)
        {
            if(cpu.A[0] != DebugThreadNameSyscall)
            {
                return;
            }

            cpu.RemoveHook(address, HandleUnknownSyscall);

            var ksCurThreadAddress = bus.GetSymbolAddress("ksCurThread");
            var lookupIPCBufferAddress = bus.GetSymbolAddress("lookupIPCBuffer");
            var lookupCapAndSlotAddress = bus.GetSymbolAddress("lookupCapAndSlot");

            ksCurThreadPhysAddress = cpu.TranslateAddress(ksCurThreadAddress, MpuAccess.Read);
            cpu.AddHook(lookupCapAndSlotAddress, HandleLookupCapAndSlotAddress);
            cpu.AddHook(lookupIPCBufferAddress, HandleLookupIPCBuffer);
        }

        private void Finalize(ICpuSupportingGdb _cpu, ulong address)
        {
            cpu.RemoveHook(address, Finalize);
            Ready = true;
            this.Log(LogLevel.Info, "Initialization complete.");
        }

        private void ksCurThreadChanged(ICpuSupportingGdb _cpu, ulong address)
        {
            foreach(var addr in breakpoints.Values.SelectMany(v => v).Where(v => v != null))
            {
                cpu.RemoveHook(addr.Value, HandleBreakpoint);
            }

            var thread = CurrentThread();
            if(!breakpoints.ContainsKey(thread))
            {
                return;
            }

            var tcb = cpu.TranslateAddress((ulong)bus.ReadDoubleWord(this.ksCurThreadPhysAddress, context: cpu) + 0x88, MpuAccess.Read);
            var pc = bus.ReadDoubleWord(tcb, context: cpu);
            cpu.AddHook(pc, HandleThreadSwitch);
        }

        private void HandleThreadSwitch(ICpuSupportingGdb _cpu, ulong address)
        {
            cpu.RemoveHook(address, HandleThreadSwitch);

            var thread = CurrentThread();
            foreach(var addr in breakpoints[thread])
            {
                if(addr == null)
                {
                    continue;
                }

                cpu.AddHook(addr.Value, HandleBreakpoint);
            }

            if(breakpoints[thread].Contains(null))
            {
                cpu.Pause();
                cpu.EnterSingleStepModeSafely(new HaltArguments(HaltReason.Breakpoint, cpu.Id, address, BreakpointType.MemoryBreakpoint), true);
            }
        }

        private void HandleBreakpoint(ICpuSupportingGdb _cpu, ulong address)
        {
            cpu.Pause();
            cpu.EnterSingleStepModeSafely(new HaltArguments(HaltReason.Breakpoint, cpu.Id, address, BreakpointType.MemoryBreakpoint), true);
        }

        private void HandleLookupCapAndSlotAddress(ICpuSupportingGdb _cpu, ulong address)
        {
            cpu.RemoveHook(address, HandleLookupCapAndSlotAddress);
            cpu.AddHook(cpu.RA, HandlePostLookupCapAndSlotAddress);
        }

        private void HandlePostLookupCapAndSlotAddress(ICpuSupportingGdb _cpu, ulong address)
        {
            var luRet = cpu.A[0];
            var paddr = cpu.TranslateAddress(luRet + 0x4UL, MpuAccess.Read);
            var underlying = bus.ReadDoubleWord(paddr, context: cpu);
            currentTCB = underlying & 0xffffff00;
        }


        private void HandleLookupIPCBuffer(ICpuSupportingGdb _cpu, ulong address)
        {
            cpu.RemoveHook(address, HandleLookupIPCBuffer);
            cpu.AddHook(cpu.RA, HandlePostLookupIPCBuffer);
        }

        private void HandlePostLookupIPCBuffer(ICpuSupportingGdb _cpu, ulong address)
        {
            var paddr = cpu.TranslateAddress(cpu.A[0] + 0x4UL, MpuAccess.Read);
            // NOTE(mwitkowski): 100 bytes is arbitrary
            var bytes = bus.ReadBytes(paddr, 100, context: cpu)
                           .TakeWhile(b => b != 0)
                           .ToArray();
            var threadName = System.Text.Encoding.ASCII.GetString(bytes);

            if(!mapping.ContainsKey(currentTCB))
            {
                mapping.Add(currentTCB, threadName);
            }
            else if(threadName.Contains("_control"))
            {
                mapping[currentTCB] = threadName;
            }

            if(pendingThreadName != null && threadName.Contains(pendingThreadName))
            {
                pendingThreadName = null;
                cpu.Pause();
                cpu.EnterSingleStepModeSafely(new HaltArguments(HaltReason.Breakpoint, cpu.Id, address, BreakpointType.MemoryBreakpoint), true);
            }
        }

        public bool BreakpointsEnabled
        {
            get
            {
                return breakpointsEnabled;
            }
            set
            {
                if(breakpointsEnabled == value)
                {
                    return;
                }

                breakpointsEnabled = value;
                var address = bus.GetSymbolAddress("restore_user_context");
                if(value)
                {
                    cpu.AddHook(address, ksCurThreadChanged);
                }
                else
                {
                    cpu.RemoveHook(address, ksCurThreadChanged);
                }
            }
        }

        public string[] Threads => mapping.Values.ToArray();

        public bool Ready { get; private set; }

        private const uint DebugThreadNameSyscall = 0xffffffef;

        private readonly Dictionary<string, SortedSet<ulong?>> breakpoints;
        private readonly Dictionary<ulong, string> mapping;
        private readonly RiscV32 cpu;
        private SystemBus bus => cpu.Bus;

        private bool breakpointsEnabled;
        private ulong ksCurThreadPhysAddress;
        private string pendingThreadName;
        private ulong currentTCB;
    }
}

