//
// Copyright (c) 2023 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 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,
        }
    }
}
