//
// Copyright (c) 2022 Google LLC
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//

using Antmicro.Renode.Core;
using Antmicro.Renode.Core.Structure;
using Antmicro.Renode.Core.Structure.Registers;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Peripherals.Sensor;

namespace Antmicro.Renode.Peripherals.Sensors
{
    public class DoubleBufferDMA: NullRegistrationPointPeripheralContainer<ICPIPeripheral>, IDoubleWordPeripheral, IKnownSize, IProvidesRegisterCollection<DoubleWordRegisterCollection>, IGPIOReceiver
    {
        public DoubleBufferDMA(Machine machine) : base(machine)
        {
            IRQ = new GPIO();
            Trigger = new GPIO();

            RegistersCollection = new DoubleWordRegisterCollection(this);
            DefineRegisters();
        }

        public override void Reset()
        {
            IRQ.Unset();
            Trigger.Unset();
            RegistersCollection.Reset();
        }

        public uint ReadDoubleWord(long offset)
        {
            return RegistersCollection.Read(offset);
        }

        public void WriteDoubleWord(long offset, uint value)
        {
            RegistersCollection.Write(offset, value);
        }

        public void OnGPIO(int number, bool value) {
            if (!value) {
                return;
            }

            if(RegisteredPeripheral == null)
            {
                this.Log(LogLevel.Warning, "Tried to enable the controller, but there is no device connected");
                return;
            }

            var data = RegisteredPeripheral.ReadFrame();
            var size = horizontalSize.Value * verticalSize.Value;
            // Restore bottom 3 bits of address.
            var addr1 = rxBuffer1Address.Value << 3;

            if((ulong)data.Length != size)
            {
                this.Log(LogLevel.Warning, "Received {0} bytes from the device, but RX DMA stream is configured for {1} bytes. This might indicate problems in the driver", data.Length, size);
            }
            
            Machine.SystemBus.WriteBytes(data, addr1);

            // TODO(jesionowski): re-enable double buffer once sw supports it
            // if(use_buffer1) {
            //     Machine.SystemBus.WriteBytes(data, rxBuffer1Address.Value);
            // } else {
            //     Machine.SystemBus.WriteBytes(data, rxBuffer2Address.Value);
            // }

            use_buffer1 = !use_buffer1;
            IRQ.Blink();
        }

        public DoubleWordRegisterCollection RegistersCollection { get; }

        public GPIO Trigger { get; }
        public GPIO IRQ { get; }

        public long Size => 0x1000;

        private void DefineRegisters()
        {
            Registers.HorizontalSize.Define(this)
                .WithValueField(0, 15, out horizontalSize, name: "HORIZONTAL_SIZE")
            ;

            Registers.VerticalSize.Define(this)
                .WithValueField(0, 14, out verticalSize, name: "VERTICAL_SIZE")
            ;

            Registers.RxBufferBaseAddress1.Define(this)
                .WithValueField(3, 29, out rxBuffer1Address, name: "ADDR1")
            ;

            Registers.RxBufferBaseAddress2.Define(this)
                .WithValueField(3, 29, out rxBuffer2Address, name: "ADDR2")
            ;
        }

        private bool use_buffer1 = true;
        private IValueRegisterField rxBuffer1Address;
        private IValueRegisterField rxBuffer2Address;
        private IValueRegisterField horizontalSize;
        private IValueRegisterField verticalSize;

        private enum Registers
        {
            HorizontalSize = 0x410,
            VerticalSize = 0x414,
            RxBufferBaseAddress1 = 0xe08,
            RxBufferBaseAddress2 = 0xf30,
        }
    }
}
