//
// 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(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,
        }
    }
}
