// Copyright 2020 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 "hex_dump_generator.h"

#include <lib/cksum.h>
#include <lib/zx/status.h>
#include <sys/stat.h>
#include <zircon/assert.h>
#include <zircon/errors.h>

#include <cstdint>
#include <iomanip>
#include <memory>
#include <string>

#include <fbl/unique_fd.h>

namespace extractor {

zx::status<std::unique_ptr<HexDumpGenerator>> HexDumpGenerator::Create(
    fbl::unique_fd input, HexDumpGeneratorOptions options) {
  if (!input || options.bytes_per_line == 0) {
    return zx::error(ZX_ERR_INVALID_ARGS);
  }

  if (lseek(input.get(), 0, SEEK_SET) != 0) {
    return zx::error(ZX_ERR_IO);
  }

  struct stat st;
  if (fstat(input.get(), &st) != 0) {
    return zx::error(ZX_ERR_FILE_BIG);
  }

  return zx::ok(std::unique_ptr<HexDumpGenerator>(
      new HexDumpGenerator(std::move(input), st.st_size, std::move(options))));
}

std::string HexDumpGenerator::BuildLine(const std::string& hex_string, off_t offset,
                                        size_t size) const {
  std::stringstream stream;

  if (options_.tag.length() > 0) {
    stream << options_.tag << " ";
  }
  if (options_.dump_offset) {
    stream << offset << "-" << offset + size - 1 << ":";
  }

  stream << hex_string << std::endl;
  return stream.str();
}

zx::status<std::string> HexDumpGenerator::DumpToString(const uint8_t* buffer, off_t offset,
                                                       size_t size) {
  ZX_ASSERT(size > 0 && size <= options_.bytes_per_line);
  std::stringstream stream;

  std::stringstream current_line;
  for (size_t i = 0; i < size; i++) {
    current_line << std::setfill('0') << std::setw(2) << std::right << std::hex << +buffer[i];
  }

  if (last_hex_string_ != current_line.str()) {
    if (skipped_bytes_ > 0) {
      stream << BuildLine("*", skip_start_offset_, skipped_bytes_);
    }

    stream << BuildLine(current_line.str(), offset, size);
    last_hex_string_ = current_line.str();
    skipped_bytes_ = 0;
  } else {
    if (skipped_bytes_ == 0) {
      skip_start_offset_ = offset;
    }
    skipped_bytes_ += options_.bytes_per_line;
  }

  if (Done()) {
    // If we are done dumping the file then the last line might be a repetation of previous line. If
    // so dump the repeated line.
    if (skipped_bytes_ > 0) {
      stream << BuildLine("*", skip_start_offset_, skipped_bytes_);
    }

    if (options_.dump_checksum) {
      stream << BuildLine("checksum: " + std::to_string(crc32_), 0, file_size_);
    }
  }

  return zx::ok(stream.str());
}

bool HexDumpGenerator::Done() const { return current_offset_ == file_size_; }

zx::status<std::string> HexDumpGenerator::GetNextLine() {
  if (Done()) {
    return zx::error(ZX_ERR_STOP);
  }

  size_t bytes_read = 0;

  uint8_t buffer[options_.bytes_per_line];

  while (bytes_read != options_.bytes_per_line) {
    auto ret = read(input_.get(), buffer + bytes_read, options_.bytes_per_line - bytes_read);

    if (ret < 0) {
      return zx::error(ZX_ERR_IO);
    }

    if (ret == 0) {
      break;
    }

    bytes_read += static_cast<size_t>(ret);
  }

  if (bytes_read == 0) {
    // We have checked whether we are "Done()" in the beginning. read should not return zero.
    return zx::error(ZX_ERR_BAD_STATE);
  }

  if (options_.dump_checksum) {
    crc32_ = crc32(crc32_, buffer, bytes_read);
  }

  off_t offset = current_offset_;
  current_offset_ += static_cast<off_t>(bytes_read);
  auto status = DumpToString(buffer, offset, bytes_read);
  return status;
}

}  // namespace extractor
