// 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_sys_io/sys_io.h"

#include <cinttypes>

#include "pw_preprocessor/concat.h"
#include "pw_status/status.h"
#include "pw_sys_io_stm32cube_private/config.h"
#include "stm32cube/stm32cube.h"

// These macros remap config options to the various STM32Cube HAL macro names.

// USART_INSTANCE defined to USARTn, where n is the USART peripheral index.
#define USART_INSTANCE PW_CONCAT(USART, PW_SYS_IO_STM32CUBE_USART_NUM)

// USART_GPIO_ALTERNATE_FUNC defined to GPIO_AF7_USARTn, where n is the USART
// peripheral index.
#define USART_GPIO_ALTERNATE_FUNC \
  PW_CONCAT(GPIO_AF7_USART, PW_SYS_IO_STM32CUBE_USART_NUM)

// USART_GPIO_PORT defined to GPIOx, where x is the GPIO port letter that the
// TX/RX pins are on.
#define USART_GPIO_PORT PW_CONCAT(GPIO, PW_SYS_IO_STM32CUBE_GPIO_PORT)
#define USART_GPIO_TX_PIN PW_CONCAT(GPIO_PIN_, PW_SYS_IO_STM32CUBE_GPIO_TX_PIN)
#define USART_GPIO_RX_PIN PW_CONCAT(GPIO_PIN_, PW_SYS_IO_STM32CUBE_GPIO_RX_PIN)

// USART_GPIO_PORT_ENABLE defined to __HAL_RCC_GPIOx_CLK_ENABLE, where x is the
// GPIO port letter that the TX/RX pins are on.
#define USART_GPIO_PORT_ENABLE \
  PW_CONCAT(__HAL_RCC_GPIO, PW_SYS_IO_STM32CUBE_GPIO_PORT, _CLK_ENABLE)

// USART_ENABLE defined to __HAL_RCC_USARTn_CLK_ENABLE, where n is the USART
// peripheral index.
#define USART_ENABLE \
  PW_CONCAT(__HAL_RCC_USART, PW_SYS_IO_STM32CUBE_USART_NUM, _CLK_ENABLE)

static UART_HandleTypeDef uart;

extern "C" void pw_sys_io_Init() {
  GPIO_InitTypeDef GPIO_InitStruct = {};

  USART_ENABLE();
  USART_GPIO_PORT_ENABLE();

  GPIO_InitStruct.Pin = USART_GPIO_TX_PIN | USART_GPIO_RX_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = USART_GPIO_ALTERNATE_FUNC;
  HAL_GPIO_Init(USART_GPIO_PORT, &GPIO_InitStruct);

  uart.Instance = USART_INSTANCE;
  uart.Init.BaudRate = 115200;
  uart.Init.WordLength = UART_WORDLENGTH_8B;
  uart.Init.StopBits = UART_STOPBITS_1;
  uart.Init.Parity = UART_PARITY_NONE;
  uart.Init.Mode = UART_MODE_TX_RX;
  uart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  uart.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&uart);
}

// This whole implementation is very inefficient because it uses the synchronous
// polling UART API and only reads / writes 1 byte at a time.
namespace pw::sys_io {
Status ReadByte(std::byte* dest) {
  if (HAL_UART_Receive(
          &uart, reinterpret_cast<uint8_t*>(dest), 1, HAL_MAX_DELAY) !=
      HAL_OK) {
    return Status::ResourceExhausted();
  }
  return OkStatus();
}

Status TryReadByte(std::byte* dest) { return Status::Unimplemented(); }

Status WriteByte(std::byte b) {
  if (HAL_UART_Transmit(
          &uart, reinterpret_cast<uint8_t*>(&b), 1, HAL_MAX_DELAY) != HAL_OK) {
    return Status::ResourceExhausted();
  }
  return OkStatus();
}

// Writes a string using pw::sys_io, and add newline characters at the end.
StatusWithSize WriteLine(const std::string_view& s) {
  size_t chars_written = 0;
  StatusWithSize result = WriteBytes(std::as_bytes(std::span(s)));
  if (!result.ok()) {
    return result;
  }
  chars_written += result.size();

  // Write trailing newline.
  result = WriteBytes(std::as_bytes(std::span("\r\n", 2)));
  chars_written += result.size();

  return StatusWithSize(OkStatus(), chars_written);
}

}  // namespace pw::sys_io
