// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/host/spiflash/ftdi_spi_interface.h"

#include <assert.h>
#include <fcntl.h>
#include <openssl/sha.h>
#include <termios.h>
#include <unistd.h>

#include <chrono>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

// Include MPSSE SPI library
extern "C" {
#include "sw/host/vendor/mpsse/mpsse.h"
}

namespace opentitan {
namespace spiflash {
namespace {

// Time to wait between attempts to check the hash in nanoseconds.
// TODO: If transmission is not successful, adapt this by an argument.
constexpr int kHashReadDelayNs = 10000;

// Time before giving up on looking for the correct hash.
constexpr int kHashReadTimeoutNs = 1000000;

// FTDI Configuration. This can be made configurable later on if needed.
constexpr int kFrequency = 1000000;  // 1MHz

enum FtdiGpioMapping {
  // SRST_N reset.
  kGpioJtagSrstN = GPIOL1,

  // JTAG SPI_N select signal.
  kGpioJtagSpiN = GPIOL2,

  // Bootstrap pin.
  kBootstrapH = GPIOL3,
};

// Resets the target to go back to boot_rom. Assumes boot_rom will enter
// bootstrap mode.
void ResetTarget(struct mpsse_context *ctx) {
  // Set bootstrap pin high
  PinHigh(ctx, kBootstrapH);

  // Enable JTAG mode by setting GPIOL2 high and toggle reset (GPIOL1)
  PinHigh(ctx, kGpioJtagSpiN);
  PinLow(ctx, kGpioJtagSrstN);
  usleep(100000);
  PinHigh(ctx, kGpioJtagSrstN);

  // Switch from JTAG to SPI mode. The delay is needed to make sure we don't
  // drop any frames.
  usleep(100000);
  PinLow(ctx, kGpioJtagSpiN);
}
}  // namespace

// Wrapper struct used to hide mpsse_context since incomplete C struct
// declarations don't play in forward declarations.
struct MpsseHandle {
  struct mpsse_context *ctx;

  explicit MpsseHandle(struct mpsse_context *new_ctx) : ctx(new_ctx) {}
  ~MpsseHandle() {
    if (ctx != nullptr) {
      Close(ctx);
    }
  }
};

FtdiSpiInterface::FtdiSpiInterface() : spi_(nullptr) {}

FtdiSpiInterface::~FtdiSpiInterface() {
  if (spi_ != nullptr) {
    // TODO: Add interface to toggle bootstrap pin.
    PinLow(spi_->ctx, kBootstrapH);
  }
}

bool FtdiSpiInterface::Init() {
  struct mpsse_context *ctx = MPSSE(SPI0, kFrequency, MSB);
  if (ctx == nullptr) {
    std::cerr << "Unable to open FTDI SPI interface." << std::endl;
    return false;
  }
  spi_ = std::make_unique<MpsseHandle>(ctx);
  ResetTarget(ctx);
  return true;
}

bool FtdiSpiInterface::TransmitFrame(const uint8_t *tx, size_t size) {
  assert(spi_ != nullptr);

  // The mpsse library is more permissive than the SpiInteface. Copying tx
  // to local buffer to handle issue internally.
  std::vector<uint8_t> tx_local(tx, tx + size);

  if (Start(spi_->ctx)) {
    std::cerr << "Unable to start spi transaction." << std::endl;
    return false;
  }

  uint8_t *tmp_rx = ::Transfer(spi_->ctx, tx_local.data(), size);
  // We're not using the result of this read, so free it right away.
  if (tmp_rx == nullptr) {
    free(tmp_rx);
  }

  if (Stop(spi_->ctx)) {
    std::cerr << "Unable to terminate spi transaction." << std::endl;
    return false;
  }
  return true;
}

bool FtdiSpiInterface::CheckHash(const uint8_t *tx, size_t size) {
  uint8_t hash[SHA256_DIGEST_LENGTH];
  SHA256_CTX sha256;
  SHA256_Init(&sha256);
  SHA256_Update(&sha256, tx, size);
  SHA256_Final(hash, &sha256);

  uint8_t *rx;

  int hash_index = 0;
  bool hash_correct = false;

  if (Start(spi_->ctx)) {
    std::cerr << "Unable to start spi transaction." << std::endl;
    return false;
  }

  auto begin = std::chrono::steady_clock::now();
  auto now = begin;
  while (!hash_correct &&
         std::chrono::duration_cast<std::chrono::microseconds>(now - begin)
                 .count() < kHashReadTimeoutNs) {
    usleep(kHashReadDelayNs);
    rx = nullptr;
    rx = ::Read(spi_->ctx, size);
    if (!rx) {
      std::cerr << "Read failed, did not allocate buffer." << std::endl;
      break;
    }

    // It appears that the hash is always the first 32 bytes in practice, but in
    // testing I've seen the hash appear at random locations in the message.
    // Checking for the hash at any location or even split between messages may
    // not be necessary, but it is probably safer.
    for (int i = 0; !hash_correct && i < SHA256_DIGEST_LENGTH; ++i) {
      if (rx[i] == hash[hash_index]) {
        ++hash_index;
        if (hash_index == SHA256_DIGEST_LENGTH) {
          hash_correct = true;
        }
      } else {
        hash_index = 0;
      }
    }
    free(rx);
    now = std::chrono::steady_clock::now();
  }

  if (Stop(spi_->ctx)) {
    std::cerr << "Unable to terminate spi transaction." << std::endl;
    return false;
  }

  if (!hash_correct) {
    std::cerr << "Didn't receive correct hash before timeout." << std::endl;
  }

  return hash_correct;
}
}  // namespace spiflash
}  // namespace opentitan
