// Copyright 2018 The Chromium OS 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 <inttypes.h>
#include <stdio.h>

#include <iostream>
#include <memory>

#include <base/check_op.h>
#include <base/command_line.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>

#include "screen-capture-utils/bo_import_capture.h"
#include "screen-capture-utils/capture.h"
#include "screen-capture-utils/crtc.h"
#include "screen-capture-utils/egl_capture.h"
#include "screen-capture-utils/png.h"

namespace screenshot {
namespace {

constexpr const char kHelpSwitch[] = "help";
constexpr const char kInternalSwitch[] = "internal";
constexpr const char kExternalSwitch[] = "external";
constexpr const char kCrtcIdSwitch[] = "crtc-id";
constexpr const char kCropSwitch[] = "crop";
constexpr const char kMethodSwitch[] = "method";

constexpr const char kHelp[] =
    "Usage: screenshot [options...] path/to/output.png\n"
    "\n"
    "Takes a screenshot and saves as a PNG file.\n"
    "By default, a screenshot is captured from any active display.\n"
    "\n"
    "Options:\n"
    "  --internal: Capture from internal display.\n"
    "  --external: Capture from external display.\n"
    "  --crtc-id=ID: Capture from the specified display.\n"
    "  --crop=WxH+X+Y: Specify a subregion to capture.\n"
    "  --method=[egl|bo]: Force capture method to EGL or bo.\n";

enum class CaptureMethod {
  AUTODETECT,
  EGL,
  BO,
};

void PrintHelp() {
  std::cerr << kHelp;
}

int Main() {
  auto* cmdline = base::CommandLine::ForCurrentProcess();

  if (cmdline->HasSwitch(kHelpSwitch) || cmdline->GetArgs().empty()) {
    PrintHelp();
    return 1;
  }

  if (cmdline->GetArgs().size() != 1) {
    LOG(ERROR) << "Must specify single output path";
    return 1;
  }

  int crtc_specs = (cmdline->HasSwitch(kInternalSwitch) ? 1 : 0) +
                   (cmdline->HasSwitch(kExternalSwitch) ? 1 : 0) +
                   (cmdline->HasSwitch(kCrtcIdSwitch) ? 1 : 0);
  if (crtc_specs > 1) {
    LOG(ERROR) << "--internal, --external and --crtc-id are exclusive";
    return 1;
  }

  bool crop_set = false;
  uint32_t x, y, width, height;
  if (cmdline->HasSwitch(kCropSwitch)) {
    auto spec = cmdline->GetSwitchValueASCII(kCropSwitch);
    int read_size;
    int scan_size = sscanf(spec.c_str(),
                           "%" SCNu32 "x%" SCNu32 "+%" SCNu32 "+%" SCNu32 "%n",
                           &width, &height, &x, &y, &read_size);
    if (scan_size != 4 || read_size != static_cast<int>(spec.size())) {
      LOG(ERROR) << "Invalid --crop specification";
      return 1;
    }
    CHECK_GT(width, 0);
    CHECK_GT(height, 0);
    crop_set = true;
  }

  CrtcFinder finder;
  if (cmdline->HasSwitch(kInternalSwitch)) {
    finder.SetSpec(CrtcFinder::Spec::kInternalDisplay);
  } else if (cmdline->HasSwitch(kExternalSwitch)) {
    finder.SetSpec(CrtcFinder::Spec::kExternalDisplay);
  } else if (cmdline->HasSwitch(kCrtcIdSwitch)) {
    uint32_t crtc_id;
    if (!base::StringToUint(cmdline->GetSwitchValueASCII(kCrtcIdSwitch),
                            &crtc_id)) {
      LOG(ERROR) << "Invalid --crtc-id specification";
      return 1;
    }
    finder.SetSpec(CrtcFinder::Spec::kById);
    finder.SetCrtcId(crtc_id);
  }

  auto crtc = finder.Find();
  if (!crtc) {
    LOG(ERROR) << "CRTC not found. Is the screen on?";
    return 1;
  }

  CaptureMethod method = CaptureMethod::AUTODETECT;
  if (cmdline->HasSwitch(kMethodSwitch)) {
    std::string method_str = cmdline->GetSwitchValueASCII(kMethodSwitch);
    if (method_str == "egl") {
      method = CaptureMethod::EGL;
    } else if (method_str == "bo") {
      method = CaptureMethod::BO;
    } else {
      LOG(ERROR) << "Invalid --method specification";
      return 1;
    }
  }

  uint32_t crtc_width;
  uint32_t crtc_height;

  crtc_width = crtc->width();
  crtc_height = crtc->height();

  if (!crop_set) {
    x = 0;
    y = 0;
    width = crtc_width;
    height = crtc_height;
  }
  CHECK_LT(x, crtc_width);
  CHECK_LT(y, crtc_height);
  CHECK_LE(x + width, crtc_width);
  CHECK_LE(y + height, crtc_height);

  if (method == CaptureMethod::AUTODETECT) {
    // TODO(andrescj): is it possible to still use the EGL path even if this
    // is nullptr? e.g., if drmModeGetFB2() fails for the CRTC but not for
    // individual planes.
    //
    // Also, it might be cleaner to move this logic to Crtc.
    if (crtc->fb2())
      method = CaptureMethod::EGL;
    else
      method = CaptureMethod::BO;
  }

  std::unique_ptr<screenshot::DisplayBuffer> display_buffer;

  if (method == CaptureMethod::EGL) {
    display_buffer.reset(
        new screenshot::EglDisplayBuffer(crtc.get(), x, y, width, height));
  } else {
    display_buffer.reset(
        new screenshot::GbmBoDisplayBuffer(crtc.get(), x, y, width, height));
  }

  screenshot::DisplayBuffer::Result result = display_buffer->Capture();
  screenshot::SaveAsPng(cmdline->GetArgs()[0].c_str(), result.buffer,
                        result.width, result.height, result.stride);
  return 0;
}

}  // namespace
}  // namespace screenshot

int main(int argc, char** argv) {
  base::CommandLine::Init(argc, argv);

  return screenshot::Main();
}
