//
// 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 System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

using Antmicro.Renode.Core;
using Antmicro.Renode.Core.Structure.Registers;
using Antmicro.Renode.Exceptions;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.Miscellaneous;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Utilities;
using Antmicro.Renode.Debugging;
using Antmicro.Renode.Sound;

namespace Antmicro.Renode.Peripherals.Sound
{
    public class Fifo
    {
        public void Write(ulong value)
        {
            lock (synclock)
            {
                if (!Full())
                {
                    fifo[cursor_w] = value;
                    cursor_w = (cursor_w + 1) & FIFO_MASK;
                    count++;
                }
            }
        }

        public ulong Read()
        {
            ulong result = 0;

            lock (synclock)
            {
                if (!Empty())
                {
                    result = fifo[cursor_r];
                    cursor_r = (cursor_r + 1) & FIFO_MASK;
                    count--;
                }

                return result;
            }
        }

        public bool Empty()
        {
            lock (synclock)
            {
                return count == 0;
            }
        }

        public bool Full()
        {
            lock (synclock)
            {
                return count == FIFO_SIZE;
            }
        }

        public void Flush()
        {
            lock (synclock)
            {
                cursor_r = 0;
                cursor_w = 0;
                count = 0;
                for (int i = 0; i < FIFO_SIZE; i++)
                    fifo[i] = 0;
            }
        }

        public override string ToString()
        {
            string result = "[";

            for (uint i = 0; i < FIFO_SIZE; i++) {
                result += (i == cursor_r) ? "r" : " ";
                result += (i == cursor_w) ? "w" : " ";
                result += String.Format("{0:X8} ", fifo[i]);
            }

            return result + "]";
        }

        public uint Count { get { lock(synclock) { return count; } } }

        const uint FIFO_SIZE = 32;
        const uint FIFO_MASK = FIFO_SIZE - 1;

        private uint cursor_r = 0;
        private uint cursor_w = 0;
        private uint count = 0;
        private ulong[] fifo = new ulong[FIFO_SIZE];

        private readonly object synclock = new object();
    }

    public class MatchaI2S : BasicDoubleWordPeripheral, IDisposable, IKnownSize, INumberedGPIOOutput
    {
        public MatchaI2S(Machine machine) : base(machine)
        {
            CreateRegisters();

            TxWatermarkIRQ = new GPIO();
            RxWatermarkIRQ = new GPIO();
            TxEmptyIRQ = new GPIO();
            RxOverflowIRQ = new GPIO();

            var irqs = new Dictionary<int, IGPIO>();
            irqs[(int)Events.TxWatermarkIRQ] = TxWatermarkIRQ;
            irqs[(int)Events.RxWatermarkIRQ] = RxWatermarkIRQ;
            irqs[(int)Events.TxEmptyIRQ] = TxEmptyIRQ;
            irqs[(int)Events.RxOverflowIRQ] = RxOverflowIRQ;
            Connections = new ReadOnlyDictionary<int, IGPIO>(irqs);

            Reset();
        }

        public override void Reset()
        {
            base.Reset();
            InputFile = "";
            OutputFile = "";

            ResetTx();
            ResetRx();
        }

        private void ResetTx()
        {
            encoder?.FlushBuffer();
            txThread = null;
            txBuffer = new Fifo();
        }

        private void ResetRx()
        {
            decoder?.Reset();
            rxThread = null;
            rxBuffer = new Fifo();

            rxTriggerLevel.Value = 0b010;
            mappedRxTriggerLevel = 8;
        }

        public void Dispose()
        {
            encoder?.Dispose();
        }

        public string InputFile { get; set; }
        public string OutputFile { get; set; }

        public const uint SampleFrequencyHz = 16_000;
        public const uint SampleSizeBits = 16;
        public const uint NumChannels = 2;
        public const uint BufferSizeWords = 64;

        private Fifo rxBuffer;
        private Fifo txBuffer;

        public IReadOnlyDictionary<int, IGPIO> Connections { get; }

        private void StartRx()
        {
            if (InputFile == "") {
                this.Log(LogLevel.Error, "Starting recording without an input file!");
                return;
            }

            decoder = new PCMDecoder(SampleSizeBits, SampleFrequencyHz, NumChannels, false, this);
            decoder.LoadFile(InputFile);

            this.Log(LogLevel.Info, "Starting recording.");
            rxThread = machine.ObtainManagedThread(ReceiveFrame, SampleFrequencyHz);
            rxThread.Start();
        }

        private void StartTx()
        {
            if (OutputFile == "") {
                this.Log(LogLevel.Error, "Starting playback without an output file!");
                return;
            }

            this.Log(LogLevel.Info, "Starting playback.");

            encoder = new PCMEncoder(SampleSizeBits, SampleFrequencyHz, NumChannels, false);
            encoder.Output = OutputFile + String.Format(".{0}.{1:d4}",
                    Process.GetCurrentProcess().Id, outputFileIdx++);
            encoder.SetBufferingBySamplesCount(1);

            txThread = machine.ObtainManagedThread(TransmitFrame, SampleFrequencyHz);
            txThread.Start();
        }

        private void StartLoopback()
        {
            this.Log(LogLevel.Info, "Starting loopback.");
            loopbackThread = machine.ObtainManagedThread(LoopbackFrame, SampleFrequencyHz);
            loopbackThread.Start();
        }

        private void StopThread(ref IManagedThread thread)
        {
            thread?.Stop();
            thread = null;
        }

        // Note: this is not a real thread! This is simply a function that is
        // called at a known frequency from the machine simulation. It must
        // always complete and never loop!
        private void TransmitFrame()
        {
            if (txBuffer.Empty()) {
                // FIFO is empty -- nothing to do except set the IRQ and return.
                this.Log(LogLevel.Debug, "I2S TX FIFO Empty.", txBuffer.Count, mappedTxTriggerLevel);
                TxEmptyIRQ.Set(txEmptyIrqEnabled.Value);
                return;
            }

            ulong sample = txBuffer.Read();
            encoder.AcceptSample((uint)((sample & 0xFFFF0000) >> 16)); // left
            encoder.AcceptSample((uint)(sample & 0x0000FFFF));         // right
            this.Log(LogLevel.Noisy, "Removed sample. Level: {0}", txBuffer.Count);

            if (txBuffer.Count < mappedTxTriggerLevel)
            {
                this.Log(LogLevel.Debug, "I2S TX FIFO Watermark (count {0} < {1}).", txBuffer.Count, mappedTxTriggerLevel);
                TxWatermarkIRQ.Set(txWatermarkIrqEnabled.Value);
            }
        }

        // Note: this is not a real thread! This is simply a function that is
        // called at a known frequency from the machine simulation. It must
        // always complete and never loop!
        private void ReceiveFrame()
        {
            // Decode left on the upper half of the sample
            ulong sample = (decoder.GetSingleSample() << 16);
            sample |= decoder.GetSingleSample();

            if (rxBuffer.Full())
            {
                this.Log(LogLevel.Noisy, "RX buffer full");
                if (rxOverflowIrqEnabled.Value)
                {
                    this.Log(LogLevel.Debug, "I2S RX FIFO Overflow (count {0}).", rxBuffer.Count);
                    RxOverflowIRQ.Set(rxOverflowIrqEnabled.Value);
                }

                // FIFO is full -- drop the sample
                return;
            }

            rxBuffer.Write(sample);
            this.Log(LogLevel.Noisy, "Added sample ({1:X}). Level: {0}", rxBuffer.Count, sample);
            this.Log(LogLevel.Noisy, rxBuffer.ToString());

            if (rxBuffer.Count >= mappedRxTriggerLevel)
            {
                this.Log(LogLevel.Debug, "I2S RX FIFO Watermark (count {0} == {1}).", rxBuffer.Count, mappedRxTriggerLevel);
                RxWatermarkIRQ.Set(rxWatermarkIrqEnabled.Value);
            }
        }

        private void LoopbackFrame()
        {
            if ((rxBuffer.Count >= 0) && (txBuffer.Count <= 1)) {
                ulong sample = rxBuffer.Read();
                txBuffer.Write(sample);
            }
        }

        private void CreateRegisters()
        {
            Registers.IrqState.Define(this)
                .WithFlag(0, name: "TX_WATERMARK", valueProviderCallback: _ => { return txBuffer.Count >= mappedTxTriggerLevel; })
                .WithFlag(1, name: "RX_WATERMARK", valueProviderCallback: _ => { return rxBuffer.Count >= mappedRxTriggerLevel; })
                .WithFlag(2, name: "TX_EMPTY", valueProviderCallback: _ => { return txBuffer.Empty(); })
                .WithFlag(3, name: "RX_OVERFLOW", valueProviderCallback: _ => { return rxBuffer.Full(); });

            Registers.IrqEnable.Define(this)
                .WithFlag(0, out txWatermarkIrqEnabled, name: "ENABLE_TX_WATERMARK")
                .WithFlag(1, out rxWatermarkIrqEnabled, name: "ENABLE_RX_WATERMARK")
                .WithFlag(2, out txEmptyIrqEnabled, name: "ENABLE_TX_EMPTY")
                .WithFlag(3, out rxOverflowIrqEnabled, name: "ENABLE_RX_OVERFLOW");

            Registers.IrqTest.Define(this)
                .WithFlag(0, name: "TEST_TX_WATERMARK",
                        writeCallback: (_, val) => { TxWatermarkIRQ.Set(val); })
                .WithFlag(1, name: "TEST_RX_WATERMARK",
                        writeCallback: (_, val) => { RxWatermarkIRQ.Set(val); })
                .WithFlag(2, name: "TEST_TX_EMPTY",
                        writeCallback: (_, val) => { TxEmptyIRQ.Set(val); })
                .WithFlag(3, name: "TEST_RX_OVERFLOW",
                        writeCallback: (_, val) => { RxOverflowIRQ.Set(val); });

            Registers.Control.Define(this)
                .WithFlag(0, out txEnable, name: "TX",
                    writeCallback: (_, val) => {
                        if (val) {
                            StartTx();
                        } else {
                            StopThread(ref txThread);
                        }
                    })
                .WithFlag(1, out rxEnable, name: "RX",
                    writeCallback: (_, val) => {
                        if (val) {
                            StartRx();
                        } else {
                            StopThread(ref rxThread);
                        }
                    })
                .WithFlag(2, out loopbackEnable, name: "SLPBK",
                    writeCallback: (_, val) => {
                        if (val) {
                            StartRx();
                            StartTx();
                            StartLoopback();
                        } else {
                            StopThread(ref rxThread);
                            StopThread(ref txThread);
                            StopThread(ref loopbackThread);
                        }
                    })
                .WithReservedBits(3, 15)
                .WithValueField(18, 6, out rxClkDivide, name: "NCO_RX")
                .WithValueField(25, 6, out txClkDivide, name: "NCO_TX");

            Registers.Status.Define32(this)
                .WithFlag(0, name: "TXFULL", valueProviderCallback: _ => { return txBuffer.Full(); })
                .WithFlag(1, name: "RXFULL", valueProviderCallback: _ => { return rxBuffer.Full(); })
                .WithFlag(2, name: "TXEMPTY", valueProviderCallback: _ => { return txBuffer.Empty(); })
                .WithFlag(3, name: "RXEMPTY", valueProviderCallback: _ => { return rxBuffer.Empty(); })
                .WithReservedBits(4, 27);

            Registers.ReadData.Define32(this)
                .WithValueField(0, 32, FieldMode.Read, name: "RDATA",
                    valueProviderCallback: _ => { 
                        ulong sample = rxBuffer.Read();
                        if (rxBuffer.Count < mappedRxTriggerLevel) {
                            RxWatermarkIRQ.Set(false);
                            this.Log(LogLevel.Noisy, "RX Watermark cleared");
                        }
                        RxOverflowIRQ.Set(false);
                        this.Log(LogLevel.Noisy, "Removed sample ({1:X}). Level: {0}", rxBuffer.Count, sample);

                        return sample;
                    });

            Registers.WriteData.Define32(this)
                .WithValueField(0, 32, name: "WDATA",
                    writeCallback: (_, val) => {
                        txBuffer.Write(val);
                        if (txBuffer.Count > mappedTxTriggerLevel) {
                            TxWatermarkIRQ.Set(false);
                            this.Log(LogLevel.Noisy, "TX Watermark cleared");
                        } 
                        TxEmptyIRQ.Set(false);
                        this.Log(LogLevel.Noisy, "Added sample ({1:X}). Level: {0}", txBuffer.Count, val);
                    });

            Registers.FifoControl.Define32(this)
                .WithFlag(0, name: "RXRST", writeCallback: (_, val) => { if (val) ResetRx(); })
                .WithFlag(1, name: "TXRST", writeCallback: (_, val) => { if (val) ResetTx(); })
                .WithValueField(2, 3, out rxTriggerLevel,
                    writeCallback: (_, val) => {
                        switch (val) {
                            case 0b000: mappedRxTriggerLevel = 1; break;
                            case 0b001: mappedRxTriggerLevel = 4; break;
                            case 0b010: mappedRxTriggerLevel = 8; break;
                            case 0b011: mappedRxTriggerLevel = 16; break;
                            case 0b100: mappedRxTriggerLevel = 30; break;
                            default:
                                this.Log(LogLevel.Error, "Trying to set invalid RX trigger level. Setting to default");
                                val = 0b010;
                                mappedRxTriggerLevel = 8;
                                break;
                        }
                    },
                    name: "RXILVL")
                .WithValueField(5, 2, out txTriggerLevel,
                    writeCallback: (_, val) => {
                        switch (val) {
                            case 0b00: mappedTxTriggerLevel = 1; break;
                            case 0b01: mappedTxTriggerLevel = 4; break;
                            case 0b10: mappedTxTriggerLevel = 8; break;
                            case 0b11: mappedTxTriggerLevel = 16; break;
                            default:
                                this.Log(LogLevel.Error, "Trying to set invalid TX trigger level. Setting to default");
                                val = 0b00;
                                mappedTxTriggerLevel = 8;
                                break;
                        }
                    },
                    name: "TXILVL")
                .WithReservedBits(7, 24);

            Registers.FifoStatus.Define32(this)
                .WithValueField(0, 6, name: "TXLVL",
                    valueProviderCallback: _ => { return txBuffer.Count; })
                .WithReservedBits(7, 9)
                .WithValueField(16, 6, name: "RXLVL",
                    valueProviderCallback: _ => { return rxBuffer.Count; })
                .WithReservedBits(22, 10);
        }

        private IFlagRegisterField txEnable;
        private IFlagRegisterField rxEnable;
        private IFlagRegisterField loopbackEnable;

        private IFlagRegisterField txWatermarkIrqEnabled;
        private IFlagRegisterField rxWatermarkIrqEnabled;
        private IFlagRegisterField txEmptyIrqEnabled;
        private IFlagRegisterField rxOverflowIrqEnabled;

        private IValueRegisterField rxClkDivide;
        private IValueRegisterField txClkDivide;
        private IValueRegisterField rxTriggerLevel;
        private IValueRegisterField txTriggerLevel;

        private int mappedRxTriggerLevel;
        private int mappedTxTriggerLevel;
        private int outputFileIdx;

        private IManagedThread rxThread;
        private IManagedThread txThread;
        private IManagedThread loopbackThread;
        private PCMDecoder decoder;
        private PCMEncoder encoder;

        public GPIO TxWatermarkIRQ { get; }
        public GPIO RxWatermarkIRQ { get; }
        public GPIO TxEmptyIRQ { get; }
        public GPIO RxOverflowIRQ { get; }

        public string DumpFifos() {
            return rxBuffer.ToString();
        }

        private enum Events
        {
            TxWatermarkIRQ = 0,  // raised if the xmit FIFO is below the high watermark
            RxWatermarkIRQ = 1,  // raised if the recv FIFO is above the high watermark
            TxEmptyIRQ     = 2,  // raised if the xmit FIFO is empty
            RxOverflowIRQ  = 3,  // raised if the recv FIFO has overflowed
        }

        private enum Registers
        {
            IrqState    = 0x00, // Current interrupt states
                                //   bit 0: TX watermark
                                //   bit 1: RX watermark
                                //   bit 2: TX empty
                                //   bit 3: RX overflow
            IrqEnable   = 0x04, // Whether or not interrupts are enabled
                                //   bit 0: TX watermark
                                //   bit 1: RX watermark
                                //   bit 2: TX empty
                                //   bit 3: RX overflow
            IrqTest     = 0x08, // IRQ testing
                                //   bit 0: TX watermark
                                //   bit 1: RX watermark
                                //   bit 2: TX empty
                                //   bit 3: RX overflow
            Control     = 0x0c, // Control register
            Status      = 0x10, // I2S Live Status register
                                //   bit 0: TX buffer full
                                //   bit 1: RX buffer full
                                //   bit 2: TX FIFO empty
                                //   bit 3: RX FIFO empty
            ReadData    = 0x14, // I2S read data
            WriteData   = 0x18, // I2S write data
            FifoControl = 0x1c, // I2S FIFO control register
                                //   bit 0: RX FIFO reset (write 1 to reset)
                                //   bit 1: TX FIFO reset (write 1 to reset)
                                //   bit 4-2: Trigger level for RX interrupts
                                //   bit 6-5: Trigger level for TX interrupts
            FifoStatus  = 0x20, // I2S FIFO status register
                                //   bit 5:0: Current fill level of TX fifo
                                //   bit 21:16: Current fill level of RX fifo.
        }

        public long Size => 0x40;
    }
}
