// Copyright 2024 The Pigweed Authors
//
// 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.
#pragma once

#include <optional>

#include "fsl_clock.h"
#include "fsl_i3c.h"
#include "pw_bytes/span.h"
#include "pw_containers/vector.h"
#include "pw_i2c/initiator.h"
#include "pw_i2c_mcuxpresso/i3c_ccc.h"
#include "pw_status/status.h"
#include "pw_sync/mutex.h"

namespace pw::i2c {

// I2C initiator interface implementation fsl_i3c driver in NXP MCUXpresso SDK.
class I3cMcuxpressoInitiator final : public pw::i2c::Initiator {
 public:
  struct Config {
    uint32_t base_address;              // I3C peripheral base address.
    uint32_t i2c_baud_rate;             // I2C baud rate in Hz.
    uint32_t i3c_open_drain_baud_rate;  // I3C open drain baud rate in Hz.
    uint32_t i3c_push_pull_baud_rate;   // I3C push pull baud rate in Hz.
    bool enable_open_drain_stop;  // Whether to emit open-drain speed STOP.
    bool enable_open_drain_high;  // Enable Open-Drain High to be 1 PPBAUD count
                                  // for I3C messages, or 1 ODBAUD.
  };
  I3cMcuxpressoInitiator(const Config& config)
      : config_(config),
        base_(reinterpret_cast<I3C_Type*>(config.base_address)) {}

  // Initializes the I3C controller peripheral as configured in the constructor.
  void Enable() PW_LOCKS_EXCLUDED(mutex_);

  // Deinitializes the I3C controller peripheral.
  void Disable() PW_LOCKS_EXCLUDED(mutex_);

  // Set dynamic address list, which will be used to assign dynamic addresses to
  // I3C devices on the bus during bus initialization step, or to determine the
  // type (I2C or I3C) for each transaction.
  //
  // Warning: dynamic address list can only be set once.
  pw::Status SetDynamicAddressList(
      pw::span<const uint8_t> dynamic_address_list);

  // Initialize the I3C bus (Dynamic address assignment)
  //
  // Warning: Users should set correct dynamic addresses (SetDynamicAddressList)
  // before calling this function.
  pw::Status Initialize() PW_LOCKS_EXCLUDED(mutex_);

 private:
  pw::Status DoTransferCcc(I3cCccAction rnw,
                           I3cCcc ccc_id,
                           pw::i2c::Address address,
                           pw::ByteSpan buffer);
  pw::Status DoWriteReadFor(pw::i2c::Address address,
                            pw::ConstByteSpan tx_buffer,
                            pw::ByteSpan rx_buffer,
                            pw::chrono::SystemClock::duration timeout)
      PW_LOCKS_EXCLUDED(mutex_);

  const Config& config_;
  I3C_Type* base_;
  i3c_device_info_t* device_list_ = nullptr;
  uint8_t device_count_ = 0;
  bool enabled_ PW_GUARDED_BY(mutex_) = false;
  pw::sync::Mutex mutex_;
  std::optional<pw::Vector<uint8_t, I3C_MAX_DEVCNT>> i3c_dynamic_address_list_;
};

}  // namespace pw::i2c
