//
// Copyright (c) 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Collections.Generic;
using System.Collections.Concurrent;
using Antmicro.Renode.Core;
using Antmicro.Renode.Debugging;
using Antmicro.Renode.Exceptions;
using Antmicro.Renode.Hooks;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Peripherals.CPU;
using Antmicro.Renode.Peripherals.Timers;
using Antmicro.Renode.Peripherals.CPU.Disassembler;
using Antmicro.Renode.Peripherals.CPU.Registers;
using Antmicro.Renode.Utilities;
using Antmicro.Renode.Time;
using Antmicro.Renode.Utilities.Binding;
using ELFSharp.ELF;
using ELFSharp.UImage;

namespace Antmicro.Renode.Peripherals.MpactCPU
{
	// Declare some additional function signatures.
	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate Int32 FuncInt32Int32ActionInt32(Int32 param0, ActionInt32 param1);
	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate Int32 FuncInt32Int32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32(Int32 param0, Int32 param1, FuncInt32UInt64IntPtrInt32 param2,
			FuncInt32UInt64IntPtrInt32 param3);
	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate Int32 FuncInt32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32(Int32 param0, FuncInt32UInt64IntPtrInt32 param1,
			FuncInt32UInt64IntPtrInt32 param2);
	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate Int32 FuncInt32Int32StringArrStringArrInt32(Int32 param0, string[] param1, string[] param2, Int32 param3);
	[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
	public delegate Int32 FuncInt32Int32Int32Bool(Int32 param0, Int32 param1, bool param2);

	public class MpactCheriotCPU : BaseCPU, ICpuSupportingGdb, ICPUWithRegisters, ICPUWithHooks, IGPIOReceiver, ITimeSink, IDisposable {
		[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
		private struct RegInfo {
			[FieldOffset(0)]
			public Int32 index;
			[FieldOffset(4)]
			public Int32 width;
			[FieldOffset(8)]
			public bool isGeneral;
			[FieldOffset(9)]
			public bool isReadOnly;
		}

		public MpactCheriotCPU(uint id, UInt64 memoryBase, UInt64 memorySize,
				       UInt64 revocationMemoryBase, UInt64 clintMMRBase,
				       string cpuType, IMachine machine, Endianess endianness,
               CpuBitness bitness = CpuBitness.Bits32)
		: base(id, cpuType, machine, endianness, bitness)
		{
			this.memoryBase = memoryBase;
			this.memorySize = memorySize;
			revocationMemBase = revocationMemoryBase;
			clintBase = clintMMRBase;
			error_ptr = Marshal.AllocHGlobal(4);
			value_ptr = Marshal.AllocHGlobal(8);
			reg_info_ptr = Marshal.AllocHGlobal(Marshal.SizeOf<RegInfo>());
			string_ptr = Marshal.AllocHGlobal(maxStringLen);
			run_cb_delegate = new ActionInt32(RunComplete);
			read_sysmem_delegate = new FuncInt32UInt64IntPtrInt32(ReadSysMemory);
			write_sysmem_delegate = new FuncInt32UInt64IntPtrInt32(WriteSysMemory);
			cpuLibraryRegistered = false;
		}

		~MpactCheriotCPU() {
			Marshal.FreeHGlobal(error_ptr);
			Marshal.FreeHGlobal(value_ptr);
			Marshal.FreeHGlobal(reg_info_ptr);
			Marshal.FreeHGlobal(string_ptr);
		}

		public override string Architecture { get { return "MpactCheriot";} }

		public override void Start()
		{
			if (!cpuLibraryRegistered)
			{
					LogAndThrowRE("Failed to register cpu library");
					return;
			}
			base.Start();

			// Simulator initialization code goes here.
			mpact_id = connect_with_sysbus((Int32)Id, maxStringLen, read_sysmem_delegate, write_sysmem_delegate);
			if (mpact_id < 0) {
				LogAndThrowRE("Failed to create simulator instance");
				return;
			}
			// Set up configuration array.
			var config_names = new string[4] {"memoryBase", "memorySize", "revocationMemoryBase", "clintMMRBase"};
			var config_values = new string[4];
			config_values[0] = "0x" + memoryBase.ToString("X");
			config_values[1] = "0x" + memorySize.ToString("X");
			config_values[2] = "0x" + revocationMemBase.ToString("X");
			config_values[3] = "0x" + clintBase.ToString("X");
			Int32 cfg_res = set_config(mpact_id, config_names, config_values, 4);
			if (cfg_res < 0) {
				LogAndThrowRE("Failed to set configuration information");
			}
		}

		public override void Reset()
		{
			base.Reset();
			instructionsExecutedThisRound = 0;
			totalExecutedInstructions = 0;
			// Call simulator to reset.
			reset(mpact_id);
		}

		public override void Dispose()
		{
			base.Dispose();
			// Cleanup: simulator and any unmanaged resources.
			halt(mpact_id, error_ptr);
			destruct(mpact_id);
		}

		public string CpuLibraryPath
		{
				get
				{
						return cpuLibraryPath;
				}
				set
				{
						if (!String.IsNullOrWhiteSpace(value))
						{
								if (cpuLibraryRegistered)
								{
										this.WarningLog("cpu library already registerd and " +
																		"should not be updated again.");
										return;
								}
								cpuLibraryPath = value;
								try
								{
										binder = new NativeBinder(this, cpuLibraryPath);
								}
								catch (System.Exception e)
								{
										LogAndThrowRE("Failed to load CPU library: " + e.Message);
								}
								cpuLibraryRegistered = true;
						}
						else
						{
								return;
						}
				}
		}

		public override ulong ExecutedInstructions => totalExecutedInstructions;

		public override ExecutionMode ExecutionMode
		{
			get
			{
				return executionMode;
			}
			set
			{
				lock(singleStepSynchronizer.Guard)
				{
					if (executionMode == value)
					{
						return;
					}

					executionMode = value;

					singleStepSynchronizer.Enabled = IsSingleStepMode;
					UpdateHaltedState();
				}
			}
		}

		[Register]
		public override RegisterValue PC
		{
			get
			{
				Int32 error = read_register(mpact_id, PC_ID, value_ptr);
				// TODO(torerik): Check for error.
				if (error < 0) {
					this.Log(LogLevel.Error, "Failed to read PC");
				}
				Int64 value = Marshal.ReadInt64(value_ptr);
				return Convert.ToUInt64(value);
			}

			set
			{
				Int32 error = write_register(mpact_id, PC_ID, value);
				// TODO(torerik): Check for error.
				if (error < 0) {
					this.Log(LogLevel.Error, "Failed to write PC");
				}
			}
		}

		protected override ExecutionResult ExecuteInstructions(ulong numberOfInstructionsToExecute, out ulong numberOfExecutedInstructions)
		{
			UInt64 instructionsExecutedThisRound = 0UL;
			ExecutionResult result = ExecutionResult.Ok;
			try
			{
				// Invoke simulator for the number of instructions.
				instructionsExecutedThisRound = step(mpact_id, numberOfInstructionsToExecute, error_ptr);
				// Parse the result.
				Int32 step_result = Marshal.ReadInt32(error_ptr);
				switch (step_result) {
					case -1:
						result = ExecutionResult.Aborted;
						break;
					case 0:
						result = ExecutionResult.Ok;
						break;
					case 1:
						result = ExecutionResult.Interrupted;
						break;
					case 2:
						result = ExecutionResult.WaitingForInterrupt;
						break;
					case 3:
						result = ExecutionResult.StoppedAtBreakpoint;
						break;
					case 4:
						result = ExecutionResult.StoppedAtWatchpoint;
						break;
					case 5:
						result = ExecutionResult.ExternalMmuFault;
						break;
					default:
						LogAndThrowRE("Unknown return value from step - " + step_result);
						break;
				}
			}
			catch (Exception)
			{
				this.NoisyLog("CPU exception detected, halting.");
				InvokeHalted(new HaltArguments(HaltReason.Abort, Id));
				return ExecutionResult.Aborted;
			}
			finally
			{
				numberOfExecutedInstructions = instructionsExecutedThisRound;
				totalExecutedInstructions += instructionsExecutedThisRound;
			}

			return result;
		}

		// ICPUWithRegisters methods implementations.
		public  void SetRegisterUnsafe(int register, RegisterValue value) {
			var status = write_register((Int32)mpact_id, (Int32)register, (UInt64)value);
			if (status < 0) {
				LogAndThrowRE("Failed to write register " + register);
			}
		}

		public  RegisterValue GetRegisterUnsafe(int register) {
			var status = read_register(mpact_id, register, value_ptr);
			if (status < 0) {
				LogAndThrowRE("Failed to read register " + register);
			}
			Int64 value = Marshal.ReadInt64(value_ptr);
			return (UInt64)value;
		}

		private void GetMpactRegisters() {
			if (registerMap.Count != 0) return;
			Int32 num_regs = get_reg_info_size(mpact_id);
			for (Int32 i = 0; i < num_regs; i++) {
				Int32 result = get_reg_info(mpact_id, i, string_ptr, reg_info_ptr);
				if (result < 0) {
					this.Log(LogLevel.Error, "Failed to get register info for index " + i);
					continue;
				}
				var reg_info = Marshal.PtrToStructure<RegInfo>(reg_info_ptr);
				var cpu_reg = new CPURegister(reg_info.index, reg_info.width, reg_info.isGeneral, reg_info.isReadOnly);
				var reg_name = Marshal.PtrToStringAuto(string_ptr);
				registerMap.Add(reg_info.index, cpu_reg);
				registerNamesMap.Add(reg_name, reg_info.index);
			}
		}

		public  IEnumerable<CPURegister> GetRegisters() {
			if (registerMap.Count == 0) {
				GetMpactRegisters();
			}
			return registerMap.Values.OrderBy(x => x.Index);
		}

		public new string[,] GetRegistersValues() {
			if (registerMap.Count == 0) {
				GetMpactRegisters();
			}
			var result = new Dictionary<string, ulong>();
			foreach (var reg in registerNamesMap) {
				var status = read_register(mpact_id, reg.Value, value_ptr);
				if (status < 0) continue;
				Int64 value = Marshal.ReadInt64(value_ptr);
				result.Add(reg.Key, Convert.ToUInt64(value));
			}
			var table = new Table().AddRow("Name", "Value");
			table.AddRows(result, x=> x.Key, x=> "0x{0:X}".FormatWith(x.Value));
			return table.ToArray();
		}

		private void LogAndThrowRE(string info)
		{
				this.Log(LogLevel.Error, info);
				throw new RecoverableException(info);
		}

	public Int32 LoadImageFile(String file_name, UInt64 address) {
		return load_image(mpact_id, file_name, address);
	}

	public void RunComplete(Int32 result) {
		Console.Error.WriteLine($"RunComplete({result})");
	}

	public void Run() {
		Int32 status = run(mpact_id, run_cb_delegate);
		Console.Error.WriteLine($"Run -> {status}");
	}

	public void OnGPIO(int number, bool value) {
		if (mpact_id <= 0) {
			this.Log(LogLevel.Noisy, "OnGPIO: no simulator, discard gpio {0}:{1}", number, value);
			return;
		}
		Int32 status = set_irq_value(mpact_id, number, value);
		if (status < 0) {
			Console.Error.WriteLine("Failure in setting irq value");
		}
	}

	public Int32 ReadSysMemory(UInt64 address, IntPtr buffer, Int32 length) {
		// Read from System Bus.
		switch (length) {
			case 1:
				var data8 = new byte[length];
				data8[0] = machine.SystemBus.ReadByte(address, this);
				Marshal.Copy(data8, 0, buffer, length);
				break;
			case 2:
				var data16 = new Int16[1];
				data16[0] = (Int16) machine.SystemBus.ReadWord(address, this);
				Marshal.Copy(data16, 0, buffer, 1);
				break;
			case 4:
				var data32 = new Int32[1];
				data32[0] = (Int32) machine.SystemBus.ReadDoubleWord(address, this);
				Marshal.Copy(data32, 0, buffer, 1);
				break;
			case 8:
				var data64 = new Int64[1];
				data64[0] = (Int64) machine.SystemBus.ReadQuadWord(address, this);
				Marshal.Copy(data64, 0, buffer, 1);
				break;
			default:
				var dataN = new byte[length];
				machine.SystemBus.ReadBytes(address, length, dataN, 0, false, this);
				Marshal.Copy(dataN, 0, buffer, length);
				break;
		}
		return length;
	}

	public Int32 WriteSysMemory(UInt64 address, IntPtr buffer, Int32 length) {
		// Create a managed buffer for the store data.
		// Copy the store data to the managed buffer.
		// Write the data to the system bus.
		switch (length) {
			case 1:
				var data8 = new byte[1];
				Marshal.Copy(buffer, data8, 0, 1);
				machine.SystemBus.WriteByte(address, data8[0], this);
				break;
			case 2:
				var data16 = new Int16[1];
				Marshal.Copy(buffer, data16, 0, 1);
				machine.SystemBus.WriteWord(address, (ushort)data16[0], this);
				break;
			case 4:
				var data32 = new Int32[1];
				Marshal.Copy(buffer, data32, 0, 1);
				machine.SystemBus.WriteDoubleWord(address, (uint)data32[0], this);
				break;
			case 8:
				var data64 = new Int64[1];
				Marshal.Copy(buffer, data64, 0, 1);
				machine.SystemBus.WriteQuadWord(address, (ulong)data64[0], this);
				break;
			default:
				var dataN = new byte[length];
				Marshal.Copy(buffer, dataN, 0, length);
				machine.SystemBus.WriteBytes(dataN, address);
				break;
		}
		return length;
	}

		// ICPUWithHooks methods.

		public void AddHookAtInterruptBegin(Action<ulong> hook) {
			throw new RecoverableException("Interrupt hooks not currently supported");
		}
		public void AddHookAtInterruptEnd(Action<ulong> hook) {
			throw new RecoverableException("Interrupt hooks not currently supported");
		}
		public void AddHookAtWfiStateChange(Action<bool> hook) {
			throw new RecoverableException("Wfi state change hook not currently supported");
		}

		public void AddHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook) {
			throw new RecoverableException("Hooks not currently supported");
		}
		public void RemoveHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook) {
		}
		public void RemoveHooksAt(ulong addr) {
		}
		public void RemoveAllHooks() {
		}

		// ICpuSuportingGdb methods.

		public void EnterSingleStepModeSafely(HaltArguments args, bool? blocking = null) {
			CheckCpuThreadId();
			ChangeExecutionModeToSingleStep(blocking);
			UpdateHaltedState();
			InvokeHalted(args);
		}

		public string GDBArchitecture { get { return "riscv:cheriot"; } }

		public List<GDBFeatureDescriptor> GDBFeatures {
			get {
				if (gdbFeatures.Any()) return gdbFeatures;

				// Populate the register map if it hasn't been done yet.
				if (registerNamesMap.Count == 0) {
					GetMpactRegisters();
				}
				var cpuGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.cpu");
				var intType = $"uint32";
				var c0_index = registerNamesMap["c0"];
				for (var i = 0u; i < 16; ++i) {
					cpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)c0_index + i, 32u, $"c{i}", intType, "general"));
				}
				var pcc_index = registerNamesMap["pcc"];
				cpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)pcc_index, 32u, "pcc", "code_ptr", "general"));
				gdbFeatures.Add(cpuGroup);

				return gdbFeatures;
			}
		}

		// End of ICpuSupportingGdb methods.

		private List<GDBFeatureDescriptor> gdbFeatures = new List<GDBFeatureDescriptor>();
		private UInt64 memoryBase;
		private UInt64 memorySize;
		private UInt64 revocationMemBase;
		private UInt64 clintBase;
		private Dictionary<Int32, CPURegister> registerMap = new Dictionary<Int32, CPURegister>();
		private Dictionary<string, Int32> registerNamesMap = new Dictionary<string, Int32>();
		private string cpuLibraryPath;
    private bool cpuLibraryRegistered;
		private string executableFile;
		private string simulationFilePath;
		private NativeBinder binder;
		private readonly object nativeLock;
		private readonly Int32 maxStringLen = 32;
		private IntPtr value_ptr {get; set;}
		private IntPtr error_ptr {get; set;}
		private IntPtr reg_info_ptr {get; set;}
		private IntPtr string_ptr {get; set;}
		private ActionInt32 run_cb_delegate;
		private FuncInt32UInt64IntPtrInt32 read_sysmem_delegate;
		private FuncInt32UInt64IntPtrInt32 write_sysmem_delegate;
#pragma warning disable 649
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32 construct_with_sysbus; // (Int32 id, Int32 callback(Uint64, IntPtr, Int32), Int32 callback(Uint64, IntPtr, Int32));
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32 connect_with_sysbus; // (Int32 id, Int32 callback(Uint64, IntPtr, Int32), Int32 callback(Uint64, IntPtr, Int32));
		[Import(UseExceptionWrapper = false)]
		private ActionInt32 destruct;  // (Int32 id);
		[Import(UseExceptionWrapper = false)]
		private ActionInt32 reset;  // (Int32 id);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32 get_reg_info_size; // (Int32 id)
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32Int32IntPtrIntPtr get_reg_info; // (Int32 id, IntPtr *name, IntPtr *struct);
		[Import(UseExceptionWrapper = false)]
		private FuncUInt64Int32StringIntPtr load_executable;  // (Int32 id, String file_name);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32StringUInt64 load_image; // (Int32 id, String file_name, UInt64 address);
		[Import(UseExceptionWrapper = false)]
        	private FuncUInt64Int32UInt64IntPtr step;  // (Int32 id, UInt64 step, IntPtr *error);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32Int32IntPtr read_register;  // (Int32 id, Int32 reg_id, IntPtr *value);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32Int32UInt64 write_register;  // (Int32 id, Int32 reg_id, UInt64 value);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32UInt64IntPtrInt32 read_memory; // (Int32 id, UInt64 address, IntPtr buffer, Int32 size);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32UInt64IntPtrInt32 write_memory; // (Int32 id, UInt64 address, IntPtr buffer, Int32 size);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32ActionInt32 run; // (Int32 id, void callback(Int32) )
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32IntPtr halt; // (Int32 id, IntPtr *value)
		// Set config.
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32StringArrStringArrInt32 set_config; // Int32 set_config(Int32 id, string[] names string[] values, Int32 size);
		[Import(UseExceptionWrapper = false)]
		private FuncInt32Int32Int32Bool set_irq_value; // Int32 set_irq_value(Int32 id, Int32 irq_no, bool value);

#pragma warning restore 649

		private Int32 mpact_id {get; set;}
		private ulong instructionsExecutedThisRound {get; set;}
		private ulong totalExecutedInstructions {get; set;}
		private const int PC_ID = 0x07b1;
	}
}

