// 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 "src/storage/extractor/c/extractor.h"

#include <lib/zx/status.h>
#include <zircon/errors.h>

#include <memory>

#include <fbl/unique_fd.h>
#include <safemath/checked_math.h>

#include "src/storage/extractor/cpp/extractor.h"

namespace extractor {

namespace {
zx_status_t map_kind_to_err(Error kind) {
  switch (kind) {
    case Error::CannotOverride:
      return ZX_ERR_ADDRESS_IN_USE;
    case Error::Exists:
      return ZX_ERR_ALREADY_EXISTS;
    case Error::NotAllowed:
      return ZX_ERR_NOT_SUPPORTED;
    case Error::SeekFailed:
    case Error::ReadFailed:
    case Error::WriteFailed:
      return ZX_ERR_IO;
    case Error::InvalidRange:
      return ZX_ERR_OUT_OF_RANGE;
    case Error::InvalidDataLength:
    case Error::InvalidOffset:
      return ZX_ERR_ADDRESS_UNREACHABLE;
    case Error::InvalidArgument:
      return ZX_ERR_INVALID_ARGS;
    case Error::ParseFailed:
      return ZX_ERR_BAD_STATE;
  }
}

zx::status<> map_error(CResult result) {
  if (result.ok) {
    return zx::ok();
  }
  return zx::error(map_kind_to_err(result.kind));
}

}  // namespace

zx::status<std::unique_ptr<Extractor>> Extractor::Create(fbl::unique_fd input_stream,
                                                         ExtractorOptions options,
                                                         fbl::unique_fd output_stream) {
  std::unique_ptr<Extractor> out(new Extractor());
  out->input_stream_ = std::move(input_stream);
  out->output_stream_ = std::move(output_stream);
  out->options_ = options;
  auto result =
      extractor_new(out->input_stream_.get(), options, out->output_stream_.get(), &out->extractor_);
  if (!result.ok) {
    return zx::error(map_kind_to_err(result.kind));
  }

  if (out->extractor_ == nullptr) {
    return zx::error(ZX_ERR_INVALID_ARGS);
  }
  return zx::ok(std::move(out));
}

zx::status<> Extractor::Add(uint64_t offset, uint64_t size, ExtentProperties properties) {
  return map_error(extractor_add(extractor_, offset, size, properties));
}

zx ::status<> Extractor::AddBlocks(uint64_t block_offset, uint64_t block_count,
                                   ExtentProperties properties) {
  return Add(safemath::CheckMul(block_offset, options_.alignment).ValueOrDie(),
             safemath::CheckMul(block_count, options_.alignment).ValueOrDie(), properties);
}

zx::status<> Extractor::AddBlock(uint64_t block_offset, ExtentProperties properties) {
  return AddBlocks(block_offset, 1, properties);
}

zx::status<> Extractor::Write() { return map_error(extractor_write(extractor_)); }

zx::status<> Extractor::Deflate(fbl::unique_fd input_stream, fbl::unique_fd output_stream,
                                fbl::unique_fd verbose_stream) {
  return map_error(
      extractor_deflate(input_stream.get(), output_stream.get(), verbose_stream.get()));
}

}  // namespace extractor
