// 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/camera/bin/factory/capture.h"

#include <lib/syslog/cpp/macros.h>

#include <functional>
#include <memory>

namespace camera {

fit::result<std::unique_ptr<Capture>, zx_status_t> Capture::Create(uint32_t stream,
                                                                   const std::string path,
                                                                   bool want_image,
                                                                   CaptureResponse callback) {
  auto capture = std::make_unique<Capture>();
  capture->stream_ = stream;
  capture->want_image_ = want_image;
  capture->image_ = std::make_unique<std::basic_string<uint8_t>>();
  capture->callback_ = std::move(callback);
  return fit::ok(std::move(capture));
}

Capture::Capture() {}

zx_status_t Capture::ValidateWriteFlags(WriteFlags flags) {
  WriteFlags in_fmt = flags & kInMask;
  switch (in_fmt) {
    case WriteFlags::IN_NV12:
    case WriteFlags::IN_BAYER8:
    case WriteFlags::IN_BAYER16:
    case WriteFlags::IN_DEFAULT:
      // OK
      break;
    default:
      return ZX_ERR_INVALID_ARGS;
  }
  WriteFlags out_fmt = flags & kOutMask;
  switch (out_fmt) {
    case WriteFlags::OUT_RAW:
    case WriteFlags::OUT_PGM:
    case WriteFlags::OUT_PNG_GRAY:
    case WriteFlags::OUT_PPM:
    case WriteFlags::OUT_PNG_RGB:
      // OK
      break;
    default:
      return ZX_ERR_INVALID_ARGS;
  }

  // unprocessed has to be gray
  if ((flags & WriteFlags::MOD_UNPROCESSED) != WriteFlags::NONE &&
      (flags & kGrayMask) == WriteFlags::NONE) {
    return ZX_ERR_INVALID_ARGS;
  }
  return ZX_OK;
}

void Capture::IntersectCrop(Crop& crop, WriteFlags flags) {
  auto& iformat = properties_.image_format;
  auto width = iformat.coded_width;
  auto height = iformat.coded_height;

  bool center_flag = (flags & WriteFlags::MOD_CENTER) == WriteFlags::MOD_CENTER;

  // 0 with or height means actual w/h
  if (crop.width == 0) {
    crop.width = width;
  }
  if (crop.height == 0) {
    crop.height = height;
  }
  // clear x,y if centering
  if (center_flag) {
    crop.x = 0;
    crop.y = 0;
  }

  struct Rect {
    uint32_t x0, y0, x1, y1;
  };

  Rect max = {0, 0, width - 1, height - 1};
  Rect want = {crop.x, crop.y, crop.x + crop.width, crop.y + crop.height};

  if (want.x0 > max.x1)
    want.x0 = max.x1;
  if (want.y0 > max.y1)
    want.y0 = max.y1;
  if (want.x1 > max.x1)
    want.x1 = max.x1;
  if (want.y1 > max.y1)
    want.y1 = max.y1;

  // & ~1 means round down to even; +1 & ~1 means round up to even; even is for YUV and bayer

  crop.width = (want.x1 - want.x0 + 1) & ~1;
  crop.height = (want.y1 - want.y0 + 1) & ~1;
  if (crop.width < 2)
    crop.width = 2;
  if (crop.height < 2)
    crop.height = 2;

  if (center_flag) {
    crop.x = (width / 2 - crop.width / 2) & ~1;
    crop.y = (height / 2 - crop.height / 2) & ~1;
  } else {
    crop.x = want.x0 & ~1;
    crop.y = want.y0 & ~1;
  }
}

zx_status_t Capture::WriteImage(FILE* fp, WriteFlags flags, Crop& crop) {
  zx_status_t status;

  status = ValidateWriteFlags(flags);
  if (status != ZX_OK) {
    return status;
  }

  auto& iformat = properties_.image_format;
  // workaround for bypass mode wrapped in NV16
  auto is_bayer_hack = (flags & WriteFlags::MOD_BAYER8HACK) != WriteFlags::NONE;
  if (is_bayer_hack && iformat.pixel_format.type == fuchsia::sysmem::PixelFormatType::NV12) {
    // TODO(fxbug.dev/58283) remove when stream format is accurate for bayer mode
    // 2200x2720 is from sensor config
    iformat.bytes_per_row = 2208;  // rounded up to %16?
    iformat.coded_width = 2200;
    iformat.coded_height = 2680;  // -40 extra lines, determined by visual inspection
  }

  if ((flags & WriteFlags::MOD_UNPROCESSED) != WriteFlags::NONE) {
    // unprocessed means return whole frame, even it it's non-image data
    iformat.coded_width = iformat.bytes_per_row;
    iformat.coded_height = static_cast<uint32_t>(image_->size() / iformat.bytes_per_row);
  }

  IntersectCrop(crop, flags);

  WriteFlags in_fmt = flags & kInMask;
  WriteFlags out_fmt = flags & kOutMask;

  uint32_t in_pixel_size = 1;
  if (in_fmt == WriteFlags::IN_DEFAULT) {
    switch (iformat.pixel_format.type) {
      case fuchsia::sysmem::PixelFormatType::NV12:
        in_fmt = is_bayer_hack ? WriteFlags::IN_BAYER8 : WriteFlags::IN_NV12;
        break;
      case fuchsia::sysmem::PixelFormatType::RGB565:
        // fxbug.dev(58283): should be VK_FORMAT_R16_UNORM compatible
        in_fmt = WriteFlags::IN_BAYER16;
        break;
      default:
        return ZX_ERR_NOT_SUPPORTED;
    }
  }
  if (in_fmt == WriteFlags::IN_BAYER16) {
    in_pixel_size = 2;
  }

  auto swap_requested = (flags & WriteFlags::MOD_SWAP) == WriteFlags::MOD_SWAP;

  // swap is only for RAW mode
  if (swap_requested && (out_fmt != WriteFlags::OUT_RAW || in_pixel_size != 2)) {
    return ZX_ERR_INVALID_ARGS;
  }

  auto is_16_bit = (flags & k16bitMask) != WriteFlags::NONE;
  uint32_t out_pixel_size = is_16_bit ? 2 : 3;  // 16-bit gray or 8-bit RGB
  uint32_t out_depth = is_16_bit ? 16 : 8;
  bool is_png = (flags & kPNGMask) != WriteFlags::NONE;
  bool is_pnm = (flags & kPNMMask) != WriteFlags::NONE;

  ConversionMethod method = nullptr;
  auto gray_requested = (flags & kGrayMask) != WriteFlags::NONE;
  if ((flags & WriteFlags::MOD_UNPROCESSED) != WriteFlags::NONE) {
    method = &Capture::Unprocessed;
    out_depth = 8;
    out_pixel_size = 1;
  } else if (in_fmt == WriteFlags::IN_NV12) {
    method = gray_requested ? &Capture::YOnly : &Capture::YUVToRGB;
  } else if (in_fmt == WriteFlags::IN_BAYER8 && gray_requested) {
    method = &Capture::RawBayer8;
  } else if (in_fmt == WriteFlags::IN_BAYER16 && gray_requested) {
    method = &Capture::RawBayer16;
  } else {
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (is_png) {
    PNGStart(crop.width, crop.height, out_depth, flags, fp);
  } else if (is_pnm) {
    // see pgm(5) & ppm(5)
    fprintf(fp, "P%d %d %d %d\n", out_fmt == WriteFlags::OUT_PGM ? 5 : 6, crop.width, crop.height,
            (1 << out_depth) - 1);
  }
  // else: raw has no header

  auto stride = iformat.bytes_per_row;
  ImageIter plane[2] = {
      // for YUV, [0] is Y, [1] is UV; [1] used for NV12 only
      {crop.x * in_pixel_size + crop.y * stride, stride},
      {iformat.coded_height * stride + crop.x * in_pixel_size + crop.y / 2, stride}};

  std::vector<uint8_t> row;
  row.resize(crop.width * out_pixel_size);

  for (uint32_t i = 0; i < crop.height; i++) {
    std::invoke(method, this, plane, crop, row);

    if (swap_requested) {
      for (uint32_t i = 0; i < crop.width; i++) {
        auto tmp = row[i * out_pixel_size];
        row[i * out_pixel_size] = row[i * out_pixel_size + 1];
        row[i * out_pixel_size + 1] = tmp;
      }
    }

    if (is_png) {
      png_write_row(png_ptr_, row.data());
    } else {
      fwrite(row.data(), 1, row.size(), fp);
    }

    plane[0].pos += plane[0].stride;
    if (i % 2 == 1) {  // 1 UV row for every 2 Y rows
      plane[1].pos += plane[1].stride;
    }
  }
  if (is_png) {
    PNGFinish();
  }
  fflush(fp);
  return is_png_error_ ? ZX_ERR_INTERNAL : ZX_OK;
}

// 8-bit Y to 16-bit gray
void Capture::YOnly(ImageIter plane[2], Crop& crop, std::vector<uint8_t>& row) {
  auto in = image_->data() + plane[0].pos;
  auto out = row.data();
  for (uint32_t i = 0; i < crop.width; i++) {
    *out++ = *in;
    *out++ = *in++;
  }
}

// 8-bit sensor data to 16-bit gray
void Capture::RawBayer8(ImageIter plane[2], Crop& crop, std::vector<uint8_t>& row) {
  auto in = image_->data() + plane[0].pos;
  auto out = row.data();
  for (uint32_t i = 0; i < crop.width; i++) {
    // fxbug.dev(58283) should copy 10 bit bayer to 16-bit gray
    *out++ = *in;
    *out++ = *in++;
  }
}

// 10+-bit sensor data to 16-bit gray
void Capture::RawBayer16(ImageIter plane[2], Crop& crop, std::vector<uint8_t>& row) {
  auto in = image_->data() + plane[0].pos;
  auto out = row.data();
  for (uint32_t i = 0; i < crop.width; i++) {
    // fxbug.dev(58283) Do we need to shift?
    *out++ = *in++;
    *out++ = *in++;
  }
}

void Capture::YUVToRGB(ImageIter plane[2], Crop& crop, std::vector<uint8_t>& row) {
  auto ypos = image_->data() + plane[0].pos;
  auto uvpos = image_->data() + plane[1].pos;
  for (uint32_t j = 0; j < crop.width; j++) {
    int32_t y = ypos[j];
    int32_t u = uvpos[(j / 2) * 2];
    int32_t v = uvpos[(j / 2) * 2 + 1];
    // android algorithm
    int rTmp = y + (static_cast<int>(1.370705) * (v - 128));
    int gTmp =
        y - (static_cast<int>(0.698001) * (v - 128)) - (static_cast<int>(0.337633) * (u - 128));
    int bTmp = y + (static_cast<int>(1.732446) * (u - 128));
#define CLIP(x) ((x) < 0 ? 0 : (x) > 255 ? 255 : (x))
    uint32_t r = CLIP(rTmp);
    uint32_t g = CLIP(gTmp);
    uint32_t b = CLIP(bTmp);
    row[j * 3 + 0] = static_cast<uint8_t>(r);
    row[j * 3 + 1] = static_cast<uint8_t>(g);
    row[j * 3 + 2] = static_cast<uint8_t>(b);
  }
}

// just copy rows
void Capture::Unprocessed(ImageIter plane[2], Crop& crop, std::vector<uint8_t>& row) {
  auto in = image_->data() + plane[0].pos;
  auto out = row.data();
  memcpy(out, in, crop.width);
}

static void png_error_fn(png_structp png_ptr, png_const_charp msg) {
  auto capture = static_cast<Capture*>(png_get_error_ptr(png_ptr));
  capture->is_png_error_ = true;
  FX_LOGS(ERROR) << "png error: " << msg;
}

static void png_warning_fn(png_structp png_ptr, png_const_charp msg) {
  FX_LOGS(WARNING) << "png warning: " << msg;
}

void Capture::PNGStart(uint32_t width, uint32_t height, uint32_t depth, WriteFlags flags,
                       FILE* fp) {
  is_png_error_ = false;
  png_ptr_ = png_create_write_struct(PNG_LIBPNG_VER_STRING, this, png_error_fn, png_warning_fn);
  png_info_ = png_create_info_struct(png_ptr_);

  png_init_io(png_ptr_, fp);
  auto is_gray = (flags & WriteFlags::OUT_PNG_GRAY) == WriteFlags::OUT_PNG_GRAY;
  auto type = is_gray ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_RGB;
  png_set_IHDR(png_ptr_, png_info_, width, height, depth, type, PNG_INTERLACE_NONE,
               PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  png_write_info(png_ptr_, png_info_);
}

void Capture::PNGFinish() {
  if (!is_png_error_) {
    png_write_end(png_ptr_, NULL);
  }
  png_destroy_write_struct(&png_ptr_, &png_info_);
}

void Capture::WritePNGAsNV12(FILE* fp) {
  Crop crop = {0, 0, 0, 0};
  WriteImage(fp, WriteFlags::IN_NV12 | WriteFlags::OUT_PNG_RGB, crop);
}

void Capture::WritePNGUnprocessed(FILE* fp, bool is_bayer) {
  Crop crop = {0, 0, 0, 0};
  WriteImage(fp,
             WriteFlags::IN_DEFAULT | WriteFlags::OUT_PNG_GRAY | WriteFlags::MOD_UNPROCESSED |
                 (is_bayer ? WriteFlags::MOD_BAYER8HACK : WriteFlags::NONE),
             crop);
}

}  // namespace camera
