// Copyright 2021 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.

#include "pw_i2c/register_device.h"

#include "pw_bytes/byte_builder.h"

namespace pw {
namespace i2c {
namespace {

// Puts the register address data into the buffer based on the size of the
// register address.
void PutRegisterAddressInByteBuilder(
    ByteBuilder& byte_builder,
    const uint32_t register_address,
    const std::endian order,
    RegisterAddressSize register_address_size) {
  // TODO(b/185952662): Simplify the call site by extending the byte builder
  //                   and endian API.
  switch (register_address_size) {
    case RegisterAddressSize::k1Byte:
      byte_builder.PutUint8(static_cast<uint8_t>(register_address));
      break;

    case RegisterAddressSize::k2Bytes:
      byte_builder.PutUint16(static_cast<uint16_t>(register_address), order);
      break;

    case RegisterAddressSize::k4Bytes:
      byte_builder.PutUint32(register_address, order);
      break;

    default:
      PW_CRASH("Invalid address size being put in byte buffer");
  }
}

void PutRegisterData16InByteBuilder(ByteBuilder& byte_builder,
                                    ConstByteSpan register_data,
                                    const std::endian order) {
  uint32_t data_pointer_index = 0;

  while (data_pointer_index < register_data.size()) {
    const uint16_t data = *reinterpret_cast<const uint16_t*>(
        register_data.data() + data_pointer_index);
    byte_builder.PutUint16(data, order);
    data_pointer_index += sizeof(data);
  }
}

Status PutRegisterData32InByteBuilder(ByteBuilder& byte_builder,
                                      ConstByteSpan register_data,
                                      const std::endian order) {
  uint32_t data_pointer_index = 0;

  while (data_pointer_index < register_data.size()) {
    const uint32_t data = *reinterpret_cast<const uint32_t*>(
        register_data.data() + data_pointer_index);
    byte_builder.PutUint32(data, order);
    data_pointer_index += sizeof(data);
  }

  if (data_pointer_index == register_data.size()) {
    return pw::OkStatus();
  } else {
    // The write data that was given doesn't align with the expected register
    // data size.
    return Status::InvalidArgument();
  }
}

}  // namespace

Status RegisterDevice::WriteRegisters(
    const uint32_t register_address,
    ConstByteSpan register_data,
    const size_t register_data_size,
    ByteSpan buffer,
    chrono::SystemClock::duration for_at_least) {
  // Make sure the buffer is big enough to handle the address and data.
  if (buffer.size() <
      register_data.size() + static_cast<uint32_t>(register_address_size_)) {
    return pw::Status::OutOfRange();
  }

  ByteBuilder builder = ByteBuilder(buffer);
  PutRegisterAddressInByteBuilder(
      builder, register_address, order_, register_address_size_);

  switch (register_data_size) {
    case 1:
      builder.append(register_data.data(), register_data.size());
      break;

    case 2:
      PutRegisterData16InByteBuilder(builder, register_data, order_);
      break;

    case 4:
      PutRegisterData32InByteBuilder(builder, register_data, order_);
      break;

    default:
      PW_CRASH("Invalid data size being put in byte buffer");
  }

  if (!builder.ok()) {
    return pw::Status::Internal();
  }

  ConstByteSpan write_buffer(builder.data(), builder.size());
  return WriteFor(write_buffer, for_at_least);
}

Status RegisterDevice::ReadRegisters(
    uint32_t register_address,
    ByteSpan return_data,
    chrono::SystemClock::duration for_at_least) {
  ByteBuffer<sizeof(register_address)> byte_buffer;

  PutRegisterAddressInByteBuilder(
      byte_buffer, register_address, order_, register_address_size_);

  if (!byte_buffer.ok()) {
    return pw::Status::Internal();
  }

  return WriteReadFor(byte_buffer.data(),
                      byte_buffer.size(),
                      return_data.data(),
                      return_data.size(),
                      for_at_least);
}

}  // namespace i2c
}  // namespace pw
