// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>

static constexpr const size_t kDataAlignment = 16;
static constexpr const size_t kBlockSize = 1024;
static constexpr const size_t kRootChecksumLength = 512;
static constexpr const uint32_t kFileFlags = 0xA;
static constexpr const uint32_t kDirectoryFlags = 0x9;
static constexpr const uint32_t kHardlinkFlags = 0x0;
static constexpr const uint32_t kMinHeaderSize = 0x20;  // For names with 15 or fewer characters
static constexpr const uint32_t kRootHeaderSizePos = 8;
static constexpr const uint32_t kRootHeaderChecksumPos = 12;

void usage() {
  std::cout << "Generate a flat romfs image from the provided files.\n";
  std::cout << "Usage: mkromfs {output} {files}...\n";
  std::cout << "Example: mkromfs ./out.img ~/foo.bin ~/bar.so\n";
}

// Round a value to the next multiple of a specified alignment
uint32_t roundup(uint32_t x, uint32_t align) { return ((x + align - 1) / align) * align; }

// Sum chunks of data interpreted as big-endian 32-bit values.
uint32_t checksum(const void* data, size_t size) {
  uint32_t ret = 0;
  for (size_t i = 0; i < size; ++i) {
    ret += reinterpret_cast<const unsigned char*>(data)[i] << (CHAR_BIT * (3 - (i % 4)));
  }
  return ret;
}

// Write data to an ostream, zero-padding to a specified alignment.
uint32_t write(std::ostream& s, const char* data, size_t size, size_t align = kDataAlignment) {
  s.write(data, size);
  while (s.tellp() % align) {
    s.put(0);
  }
  return checksum(data, size);
}

// Write value as big-endian to the stream.
uint32_t write(std::ostream& s, uint32_t value) {
  union pun {
    uint32_t u;
    char c[sizeof(u)];
  };
  static constexpr const pun test{0x11223344};
  if (test.c[0] == 0x11) {
    return write(s, reinterpret_cast<char*>(&value), sizeof(value), sizeof(value));
  }
  pun le = {value};
  pun be{};
  for (size_t i = 0; i < sizeof(le.u); ++i) {
    be.c[i] = le.c[sizeof(le.u) - 1 - i];
  }
  return write(s, reinterpret_cast<char*>(&be), sizeof(be), sizeof(be));
}

// Read the entire contents of the specified file and return it in a char vector.
std::vector<char> read(std::string path) {
  std::ifstream file(path, std::ios::binary | std::ios::ate);
  if (!file) {
    std::cerr << "Error: file could not be opened for reading: " << path << std::endl;
    exit(-1);
  }
  std::vector<char> contents(file.tellg());
  file.seekg(0, std::ios::beg);
  file.read(contents.data(), contents.size());
  return contents;
}

int main(int argc, char* argv[]) {
  if (argc < 2) {
    usage();
    exit(-1);
  }

  // Open the output image.
  std::fstream image(argv[1], std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc);
  if (!image) {
    std::cerr << "Error: file could not be opened for writing: " << argv[3] << std::endl;
    exit(-1);
  }

  // Write the main header.
  static const char* magic = "-rom1fs-";
  static const char* label = "romfs";
  image.write(magic, strlen(magic));       // Magic
  write(image, 0);                         // Placeholder for size
  write(image, 0);                         // Placeholder for checksum
  write(image, label, strlen(label) + 1);  // Label

  // Write the root directory.
  {
    uint32_t csum = 0;
    uint32_t first_header = image.tellp();
    uint32_t next_header = first_header + kMinHeaderSize;
    csum += write(image, next_header | kDirectoryFlags);  // Next header
    next_header += kMinHeaderSize;
    csum += write(image, next_header);  // First file in directory
    csum += write(image, 0);            // No size
    csum += checksum(".", 1);
    write(image, csum);
    write(image, ".", 2);
    write(image, kHardlinkFlags);
    csum = write(image, first_header);
    write(image, 0);  // No size
    csum += checksum("..", 2);
    write(image, csum);
    write(image, "..", 3);
  }

  // Add file entries.
  for (int i = 2; i < argc; ++i) {
    auto contents = read(argv[i]);
    std::string path = argv[i];
    auto pos = path.rfind('/');
    std::string filename = pos == path.npos ? path : path.substr(pos + 1);
    uint32_t next = kFileFlags;
    if (i < argc - 1) {
      // Calculate next file offset
      uint32_t offset = image.tellp();
      offset += kDataAlignment;                                  // Initial header contents
      offset += roundup(filename.length() + 1, kDataAlignment);  // Name field
      offset += roundup(contents.size(), kDataAlignment);        // Data field
      next |= offset;
    }
    write(image, next);
    write(image, 0);  // Spec field unused
    write(image, contents.size());
    uint32_t csum = next;
    csum += contents.size();
    csum += checksum(filename.c_str(), filename.length());
    csum += checksum(contents.data(), contents.size());
    write(image, csum);
    write(image, filename.c_str(), filename.length() + 1);
    write(image, contents.data(), contents.size());
  }

  // Save the total size of the image.
  uint32_t image_size = image.tellp();

  // Pad the image to block size.
  std::vector<char> zeros(roundup(image.tellp(), kBlockSize) - image.tellp());
  image.write(zeros.data(), zeros.size());

  // Patch in the total image size.
  image.seekp(kRootHeaderSizePos, std::ios::beg);
  write(image, image_size);

  // Read back the image data and patch in the checksum.
  std::vector<char> base(kRootChecksumLength);
  image.seekg(0, std::ios::beg);
  image.read(base.data(), base.size());
  uint32_t csum = checksum(base.data(), base.size());
  image.seekp(kRootHeaderChecksumPos, std::ios::beg);
  write(image, -csum);

  return 0;
}
