//
// Copyright (c) 2010-2023 Antmicro
// Copyright (c) 2011-2015 Realtime Embedded
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Core;
using Antmicro.Renode.Peripherals;
using Antmicro.Renode.Utilities;
using Antmicro.Renode.Logging;
using System.Collections.Generic;
using Antmicro.Renode.Core.Structure.Registers;

namespace Antmicro.Renode.Peripherals.Miscellaneous
{
    public class ESP32S3_RTC_I2C_PWDET : IBytePeripheral, IDoubleWordPeripheral, IKnownSize
    {
        public ESP32S3_RTC_I2C_PWDET(Machine machine)
        {
            var registersMap = new Dictionary<long, DoubleWordRegister>
            {
                {(long)Registers.I2C_MST_ANA_CONF0, new DoubleWordRegister(this)
                    .WithFlag(2, FieldMode.Read | FieldMode.Write, name: "BBPLL_STOP_FORCE_HIGH")
                    .WithFlag(3, FieldMode.Read | FieldMode.Write, name: "BBPLL_STOP_FORCE_LOW")
                    .WithFlag(24, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => true, name: "BBPLL_CAL_DONE")
                },
                // {(long)Registers.ANA_CONFIG, new DoubleWordRegister(this)
                //     .WithValueField(0, 8, FieldMode.Read | FieldMode.Write, name: "CONFIG")
                //     .WithFlag(17, FieldMode.Read | FieldMode.Write, name: "BBPLL")
                //     .WithFlag(18, FieldMode.Read | FieldMode.Write, name: "SAR")
                // },
                // {(long)Registers.ANA_CONFIG2, new DoubleWordRegister(this)
                //     .WithFlag(16, FieldMode.Read | FieldMode.Write, name: "SAR_CFG2")
                // },
                // {(long)Registers.PWDET_CONF, new DoubleWordRegister(this)
                //     .WithFlag(6, FieldMode.Read | FieldMode.Write, name: "SAR_POWER_CNTL")
                //     .WithFlag(7, FieldMode.Read | FieldMode.Write, name: "SAR_POWER_FORCE")
                // },
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }

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

        public byte ReadByte(long offset)
        {
            if (offset % 4 != 0)
            {
                // in the current configuration, only the lowest byte
                // contains a meaningful data
                return 0;
            }
            return (byte)ReadDoubleWord(offset);
        }

        public void Reset()
        {
            // base.Reset();
            registers.Reset();

            // UpdateInterrupts();
        }

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

        public void WriteByte(long offset, byte value)
        {
            if (offset % 4 != 0)
            {
                // in the current configuration, only the lowest byte
                // contains a meaningful data
                return;
            }

            WriteDoubleWord(offset, value);
        }

        public long Size => 0x17C;
        private readonly DoubleWordRegisterCollection registers;

        private enum Registers : long
        {
            I2C_MST_ANA_CONF0 = 0x40,
            ANA_CONFIG = 0x44,
            ANA_CONFIG2 = 0x48,
            PWDET_CONF = 0x60,
        }
    }
}
