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

#include <assert.h>
#include <getopt.h>

#include <fstream>
#include <memory>
#include <sstream>
#include <string>

#include "ftdi_spi_interface.h"
#include "spi_interface.h"
#include "updater.h"
#include "verilator_spi_interface.h"

namespace {

using opentitan::spiflash::FtdiSpiInterface;
using opentitan::spiflash::SpiInterface;
using opentitan::spiflash::Updater;
using opentitan::spiflash::VerilatorSpiInterface;

constexpr char kUsageString[] = R"R( usage options:
  --input=Input image in binary format.
  [--verilator=filehandle] Enables Verilator mode with SPI filehandle.)R";

// SPI flash configuration options.
struct SpiFlashOpts {
  // Input file in binary format.
  std::string input;

  // Target SPI device handle.
  std::string target;

  // Set to true to target Verilator environment.
  bool verilator = false;
};

// Get |filename| contents and store them in |contents|. Using std::string for
// |filename| because underlying open file call requires a C string.
bool GetFileContents(const std::string &filename, std::string *contents) {
  assert(contents);
  std::ifstream file_stream(filename, std::ios::in | std::ios::binary);
  if (!file_stream) {
    std::cerr << "Unable to open: " << filename << " errno: " << errno
              << std::endl;
    return false;
  }
  std::ostringstream in_stream;
  in_stream << file_stream.rdbuf();
  file_stream.close();
  *contents = in_stream.str();
  return true;
}

// Prints help menu.
static void PrintUsage(int argc, char *argv[]) {
  assert(argc >= 1);
  std::cerr << argv[0] << kUsageString << std::endl;
}

// Parse command line arguments and store results in |options|.
bool ParseArgs(int argc, char **argv, SpiFlashOpts *options) {
  assert(options);
  const struct option long_options[] = {
      {"input", required_argument, nullptr, 'i'},
      {"verilator", required_argument, nullptr, 's'},
      {"help", no_argument, nullptr, 'h'},
      {nullptr, no_argument, nullptr, 0}};

  while (true) {
    int c = getopt_long(argc, argv, "i:s:h?", long_options, nullptr);
    if (c == -1) {
      return true;
    }

    switch (c) {
      case 0:
        break;
      case 'i':
        options->input = optarg;
        break;
      case 's':
        options->verilator = true;
        options->target = optarg;
        break;
      case '?':
      case 'h':
        PrintUsage(argc, argv);
      default:;
    }
  }
  return true;
}

}  // namespace

int main(int argc, char **argv) {
  SpiFlashOpts spi_flash_options;
  if (!ParseArgs(argc, argv, &spi_flash_options)) {
    std::cerr << "Failed to parse command line options." << std::endl;
    return 1;
  }

  std::unique_ptr<SpiInterface> spi;
  if (spi_flash_options.verilator) {
    spi = std::make_unique<VerilatorSpiInterface>(spi_flash_options.target);
  } else {
    spi = std::make_unique<FtdiSpiInterface>();
  }
  if (!spi->Init()) {
    return 1;
  }

  Updater::Options options;
  if (!GetFileContents(spi_flash_options.input, &options.code)) {
    return 1;
  }
  Updater updater(options, std::move(spi));
  return updater.Run() ? 0 : 1;
}
