// Copyright 2022 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.

#ifndef SRC_LIB_ZXDUMP_DUMP_FILE_H_
#define SRC_LIB_ZXDUMP_DUMP_FILE_H_

#include <lib/fit/result.h>
#include <lib/zxdump/buffer.h>
#include <lib/zxdump/types.h>
#include <zircon/assert.h>

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>

#include <fbl/unique_fd.h>

#include "core.h"
#include "job-archive.h"

namespace zxdump::internal {

inline constexpr size_t kHeaderProbeSize = std::max(kMinimumElf, kMinimumArchive);

// The bounds of an archive member file inside the underlying real dump file.
// Member files inside nested archives have flat offsets into the real file.
struct FileRange {
  static constexpr FileRange Unbounded() { return {0, std::numeric_limits<size_t>::max()}; }

  bool empty() const { return size == 0; }

  // Subdivide this range by a subrange.  The given subrange must be valid with
  // this range as its base.  The returned range is a subrange relative to the
  // original base of this range, no earlier or larger than this range.
  FileRange operator/(FileRange subrange) const {
    ZX_DEBUG_ASSERT(subrange.offset <= size);
    ZX_DEBUG_ASSERT(size - subrange.offset >= subrange.size);
    subrange.offset += offset;
    return subrange;
  }

  FileRange& operator/=(FileRange subrange) {
    *this = *this / subrange;
    return *this;
  }

  FileRange operator/(size_t keep_prefix) const { return *this / FileRange{0, keep_prefix}; }

  FileRange& operator/=(size_t keep_prefix) {
    *this = *this / keep_prefix;
    return *this;
  }

  FileRange operator%(size_t remove_prefix) const {
    ZX_DEBUG_ASSERT(remove_prefix <= size);
    return *this / FileRange{remove_prefix, size - remove_prefix};
  }

  FileRange& operator%=(size_t remove_prefix) {
    *this = *this % remove_prefix;
    return *this;
  }

  uint64_t offset;
  uint64_t size;
};

// Each open dump file is one of these.
class DumpFile {
 public:
  virtual ~DumpFile();

  // Read a new dump file, using mmap if possible or else stdio.
  static fit::result<Error, std::unique_ptr<DumpFile>> Open(fbl::unique_fd fd,
                                                            bool try_mmap = true);

  // Returns true if the probed bytes indicate a compressed file.  The buffer
  // is expected to be at least kHeaderProbeSize to be able to match anything.
  static bool IsCompressed(ByteView header);

  // Return a new DumpFile that decompresses part of this one by doing
  // ReadEphemeral calls on it.  The new DumpFile's lifetime must not exceed
  // this object's lifetime.  The underlying object should not be used for
  // ReadEphemeral while the decompressor object is being used.
  fit::result<Error, std::unique_ptr<DumpFile>> Decompress(FileRange where, ByteView header);

  // Return the size of the file.  This may not be known for a streaming input,
  // in which case this value acts only as an upper bound.
  virtual size_t size() const = 0;

  size_t size_bytes() const { return size(); }

  // Reduce resources when no more reading will be done but the object is kept
  // alive for ReadPermanent results.
  virtual void shrink_to_fit() = 0;

  // Read a range of the file, yielding a pointer that's valid as long as this
  // object lives.  When not doing mmap, this has to copy it all in memory.
  virtual fit::result<Error, ByteView> ReadPermanent(FileRange fr) = 0;

  // Read a range of the file, yielding a pointer that's only guaranteed to be
  // valid until the next ReadEphemeral (or ReadProbe) call on the same object.
  virtual fit::result<Error, ByteView> ReadEphemeral(FileRange fr) = 0;

  // This does ReadEphemeral (and so it invalidates past ReadEphemeral results
  // and vice versa), but if the dump file ends before the whole range, just
  // return a shorter range rather than the "truncated dump" error.
  virtual fit::result<Error, ByteView> ReadProbe(FileRange fr) = 0;

  // Read a range of the file, yielding a Buffer object whose lifetime is tied
  // to the lifetime of this DumpFile object.  The given range is the minimum
  // range that must be read.  If less is available, failure is returned
  // (possibly using the "truncated dump" error).  More may be returned if it
  // is conveniently at hand.
  virtual fit::result<Error, Buffer<>> ReadMemory(FileRange fr) = 0;

 private:
  // This is used by both Stdio and Zstd.
  using ByteVector = std::vector<std::byte>;

  // These are the different implementation subclasses.
  class Stdio;
  class Mmap;
  class Zstd;
};

// Helpers for some common errors.

constexpr auto TruncatedDump() {
  return fit::error(Error{
      "truncated dump",
      ZX_ERR_OUT_OF_RANGE,
  });
}

constexpr auto CorruptedDump() {
  return fit::error(Error{
      "corrupted dump",
      ZX_ERR_IO_DATA_INTEGRITY,
  });
}

}  // namespace zxdump::internal

#endif  // SRC_LIB_ZXDUMP_DUMP_FILE_H_
