// 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 "image_io_util.h"

#include <lib/fzl/vmo-mapper.h>
#include <lib/syslog/cpp/macros.h>

#include <vector>

#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"

namespace camera {

fit::result<std::unique_ptr<ImageIOUtil>, zx_status_t> ImageIOUtil::Create(
    fuchsia::sysmem::BufferCollectionInfo_2* buffer_collection, const std::string& dir_path) {
  if (buffer_collection->buffer_count <= 0) {
    FX_LOGS(DEBUG) << "Failed to create ImageIOUtil with empty BufferCollection.";
    return fit::error(ZX_ERR_INVALID_ARGS);
  }

  fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_clone;
  zx_status_t status = buffer_collection->Clone(&buffer_collection_clone);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to clone BufferCollection.";
    return fit::error(status);
  }
  auto stream_io = std::make_unique<ImageIOUtil>(std::move(buffer_collection_clone), dir_path);

  if (!files::CreateDirectory(stream_io->GetDirpath())) {
    FX_LOGS(ERROR) << "Failed to create on-disk directory to write to.";
    return fit::error(ZX_ERR_IO);
  }

  return fit::ok(std::move(stream_io));
}

// TODO(nzo): add functionality to ensure all previously written images (i.e. before this
// ImageIOUtil was created) are also deleted.
zx_status_t ImageIOUtil::DeleteImageData() {
  bool delete_status = true;
  if (dir_path_.empty()) {
    for (uint32_t i = 0; i < num_image_; ++i) {
      delete_status &= files::DeletePath(GetFilepath(i), false);
    }
  } else {
    delete_status = files::DeletePath(GetDirpath(), true);
  }

  return delete_status ? ZX_OK : ZX_ERR_IO;
}

zx_status_t ImageIOUtil::WriteImageData(uint32_t id) {
  if (id >= buffer_collection_.buffer_count) {
    FX_LOGS(ERROR) << "An invalid buffer id was passed in.";
    return ZX_ERR_INVALID_ARGS;
  }
  // TODO(nzo): change this to use information from ImageFormat_2 instead.
  size_t num_bytes = buffer_collection_.settings.buffer_settings.size_bytes;

  fzl::VmoMapper mapper;
  zx_status_t status =
      mapper.Map(buffer_collection_.buffers[id].vmo, 0, num_bytes, ZX_VM_PERM_READ);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to map vmo.";
    return status;
  }

  if (!files::WriteFile(GetFilepath(num_image_), static_cast<const char*>(mapper.start()),
                        num_bytes)) {
    FX_LOGS(ERROR) << "Failed to write to file on disk.";
    return ZX_ERR_IO;
  }

  FX_LOGS(INFO) << "Image written to disk.\n Run `fx scp " << GetFilepath(num_image_)
                << " ~/[HOST DESTINATION]` to transfer the file from device.";
  ++num_image_;

  return ZX_OK;
}

}  // namespace camera
