// Copyright (c) 2010 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 <getopt.h>

#include <string>

#include "media_v4l2_device.h"

/* Test lists */
static const char kDefaultTestList[] = "default";
static const char kHalv3TestList[] = "halv3";
static const char kCertificationTestList[] = "certification";

bool ExerciseControl(V4L2Device* v4l2_dev, uint32_t id, const char* control) {
  v4l2_queryctrl query_ctrl;
  if (v4l2_dev->QueryControl(id, &query_ctrl)) {
    if (!v4l2_dev->SetControl(id, query_ctrl.maximum))
      printf("[Warning] Can not set %s to maximum value\n", control);
    if (!v4l2_dev->SetControl(id, query_ctrl.minimum))
      printf("[Warning] Can not set %s to minimum value\n", control);
    if (!v4l2_dev->SetControl(id, query_ctrl.default_value))
      printf("[Warning] Can not set %s to default value\n", control);
  } else {
    printf("[Warning] Can not query control name :%s\n", control);
    return false;
  }
  return true;
}

void TestMultipleOpen(const char* dev_name) {
  V4L2Device v4l2_dev1(dev_name, 4);
  V4L2Device v4l2_dev2(dev_name, 4);
  if (!v4l2_dev1.OpenDevice()) {
    printf("[Error] Can not open device '%s' for the first time\n", dev_name);
    exit(EXIT_FAILURE);
  }
  if (!v4l2_dev2.OpenDevice()) {
    printf("[Error] Can not open device '%s' for the second time\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_dev1.CloseDevice();
  v4l2_dev2.CloseDevice();
  printf("[OK ] V4L2DeviceTest.MultipleOpen\n");
}

void TestMultipleInit(const char* dev_name, V4L2Device::IOMethod io) {
  V4L2Device::ConstantFramerate constant_framerate =
      V4L2Device::DEFAULT_FRAMERATE_SETTING;
  V4L2Device v4l2_dev1(dev_name, 4);
  V4L2Device v4l2_dev2(dev_name, 4);
  if (!v4l2_dev1.OpenDevice()) {
    printf("[Error] Can not open device '%s' for the first time\n", dev_name);
    exit(EXIT_FAILURE);
  }
  if (!v4l2_dev2.OpenDevice()) {
    printf("[Error] Can not open device '%s' for the second time\n", dev_name);
    exit(EXIT_FAILURE);
  }

  if (!v4l2_dev1.InitDevice(io, 640, 480, V4L2_PIX_FMT_YUYV, 30,
                            constant_framerate, 0)) {
    printf("[Error] Can not init device '%s' for the first time\n", dev_name);
    exit(EXIT_FAILURE);
  }

  // multiple streaming request should fail.
  if (v4l2_dev2.InitDevice(io, 640, 480, V4L2_PIX_FMT_YUYV, 30,
                           constant_framerate, 0)) {
    printf("[Error] Multiple init device '%s' should fail\n", dev_name);
    exit(EXIT_FAILURE);
  }

  v4l2_dev1.UninitDevice();
  v4l2_dev2.UninitDevice();
  v4l2_dev1.CloseDevice();
  v4l2_dev2.CloseDevice();
  printf("[OK ] V4L2DeviceTest.MultipleInit\n");
}

// EnumInput and EnumStandard are optional.
void TestEnumInputAndStandard(const char* dev_name) {
  V4L2Device v4l2_dev1(dev_name, 4);
  if (!v4l2_dev1.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_dev1.EnumInput();
  v4l2_dev1.EnumStandard();
  v4l2_dev1.CloseDevice();
  printf("[OK ] V4L2DeviceTest.EnumInputAndStandard\n");
}

void TestEnumControl(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_dev.EnumControl();
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.EnumControl\n");
}

void TestSetControl(const char* dev_name, bool constant_framerate_supported) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  // Test mandatory controls.
  if (constant_framerate_supported &&
      !ExerciseControl(&v4l2_dev, V4L2_CID_EXPOSURE_AUTO_PRIORITY,
                       "exposure_auto_priority")) {
    exit(EXIT_FAILURE);
  }

  // Test optional controls.
  ExerciseControl(&v4l2_dev, V4L2_CID_BRIGHTNESS, "brightness");
  ExerciseControl(&v4l2_dev, V4L2_CID_CONTRAST, "contrast");
  ExerciseControl(&v4l2_dev, V4L2_CID_SATURATION, "saturation");
  ExerciseControl(&v4l2_dev, V4L2_CID_GAMMA, "gamma");
  ExerciseControl(&v4l2_dev, V4L2_CID_HUE, "hue");
  ExerciseControl(&v4l2_dev, V4L2_CID_GAIN, "gain");
  ExerciseControl(&v4l2_dev, V4L2_CID_SHARPNESS, "sharpness");
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.SetControl\n");
}

// SetCrop is optional.
void TestSetCrop(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_cropcap cropcap;
  memset(&cropcap, 0, sizeof(cropcap));
  if (v4l2_dev.GetCropCap(&cropcap)) {
    v4l2_crop crop;
    memset(&crop, 0, sizeof(crop));
    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    crop.c = cropcap.defrect;
    v4l2_dev.SetCrop(&crop);
  }
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.SetCrop\n");
}

// GetCrop is optional.
void TestGetCrop(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_crop crop;
  memset(&crop, 0, sizeof(crop));
  crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  v4l2_dev.GetCrop(&crop);
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.GetCrop\n");
}

void TestProbeCaps(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_capability caps;
  if (!v4l2_dev.ProbeCaps(&caps, true)) {
    printf("[Error] Can not probe caps on device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  if (!(caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
    printf("<<< Info: %s does not support video capture interface.>>>\n",
        dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.ProbeCaps\n");
}

void TestEnumFormats(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  if (!v4l2_dev.EnumFormat(NULL)) {
    printf("[Error] Can not enumerate format on device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.EnumFormats\n");
}

void TestEnumFrameSize(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  uint32_t format_count = 0;
  if (!v4l2_dev.EnumFormat(&format_count)) {
    printf("[Error] Can not enumerate format on device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  for (uint32_t i = 0; i < format_count; ++i) {
    uint32_t pixfmt;
    if (!v4l2_dev.GetPixelFormat(i, &pixfmt)) {
      printf("[Error] Enumerate format error on device '%s'\n", dev_name);
      exit(EXIT_FAILURE);
    }
    if (!v4l2_dev.EnumFrameSize(pixfmt, NULL)) {
      printf("[Warning] Enumerate frame size error on device '%s'\n", dev_name);
      exit(EXIT_FAILURE);
    };
  }
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.EnumFrameSize\n");
}

void TestEnumFrameInterval(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  uint32_t format_count = 0;
  if (!v4l2_dev.EnumFormat(&format_count)) {
    printf("[Error] Can not enumerate format on device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  for (uint32_t i = 0; i < format_count; ++i) {
    uint32_t pixfmt;
    if (!v4l2_dev.GetPixelFormat(i, &pixfmt)) {
      printf("[Error] Get format error on device '%s'\n", dev_name);
      exit(EXIT_FAILURE);
    }
    uint32_t size_count;
    if (!v4l2_dev.EnumFrameSize(pixfmt, &size_count)) {
      printf("[Error] Enumerate frame size error on device '%s'\n", dev_name);
      exit(EXIT_FAILURE);
    };

    for (uint32_t j = 0; j < size_count; ++j) {
      uint32_t width, height;
      if (!v4l2_dev.GetFrameSize(j, pixfmt, &width, &height)) {
        printf("[Error] Get frame size error on device '%s'\n", dev_name);
        exit(EXIT_FAILURE);
      };
      if (!v4l2_dev.EnumFrameInterval(pixfmt, width, height, NULL)) {
        printf("[Error] Enumerate frame interval error on device '%s'\n",
            dev_name);
        exit(EXIT_FAILURE);
      };
    }
  }
  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.EnumFrameInterval\n");
}

void TestFrameRate(const char* dev_name) {
  V4L2Device v4l2_dev(dev_name, 4);
  if (!v4l2_dev.OpenDevice()) {
    printf("[Error] Can not open device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  v4l2_streamparm param;
  if (!v4l2_dev.GetParam(&param)) {
    printf("[Error] Can not get stream param on device '%s'\n", dev_name);
    exit(EXIT_FAILURE);
  }
  // we only try to adjust frame rate when it claims can.
  if (param.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
    if (!v4l2_dev.SetParam(&param)) {
      printf("[Error] Can not set stream param on device '%s'\n", dev_name);
      exit(EXIT_FAILURE);
    }
  } else {
    printf("[Info] %s does not support TIMEPERFRAME.\n", dev_name);
  }

  v4l2_dev.CloseDevice();
  printf("[OK ] V4L2DeviceTest.FrameRate\n");
}

static void PrintUsage(int argc, char** argv) {
  printf("Usage: %s [options]\n\n"
         "Options:\n"
         "--help               Print usage\n"
         "--device=DEVICE_NAME Video device name [/dev/video]\n"
         "--usb-info=VID:PID   Device vendor id and product id\n"
         "--test-list=TEST     Select different test list\n"
         "                     [%s | %s | %s]\n",
         argv[0], kDefaultTestList, kHalv3TestList,
         kCertificationTestList);
}

static const char short_options[] = "?d:u:t:";
static const struct option long_options[] = {
        { "help",      no_argument,       NULL, '?' },
        { "device",    required_argument, NULL, 'd' },
        { "usb-info",  required_argument, NULL, 'u' },
        { "test-list", required_argument, NULL, 't' },
        { 0, 0, 0, 0 }
};

int main(int argc, char** argv) {
  std::string dev_name = "/dev/video";
  std::string usb_info = "";
  std::string test_list = kDefaultTestList;

  // Parse the command line.
  for (;;) {
    int32_t index;
    int32_t c = getopt_long(argc, argv, short_options, long_options, &index);
    if (-1 == c)
      break;
    switch (c) {
      case 0:  // getopt_long() flag.
        break;
      case '?':
        PrintUsage(argc, argv);
        return EXIT_SUCCESS;
      case 'd':
        // Initialize default v4l2 device name.
        dev_name = optarg;
        break;
      case 'u':
        usb_info = optarg;
        break;
      case 't':
        test_list = optarg;
        break;
      default:
        PrintUsage(argc, argv);
        return EXIT_FAILURE;
    }
  }

  bool constant_framerate = (test_list != kDefaultTestList);
  printf("[Info] constant framerate: %d\n", constant_framerate);

  TestMultipleOpen(dev_name.c_str());
  TestMultipleInit(dev_name.c_str(), V4L2Device::IO_METHOD_MMAP);
  TestMultipleInit(dev_name.c_str(), V4L2Device::IO_METHOD_USERPTR);
  TestEnumInputAndStandard(dev_name.c_str());
  TestEnumControl(dev_name.c_str());
  TestSetControl(dev_name.c_str(), constant_framerate);
  TestSetCrop(dev_name.c_str());
  TestGetCrop(dev_name.c_str());
  TestProbeCaps(dev_name.c_str());
  TestEnumFormats(dev_name.c_str());
  TestEnumFrameSize(dev_name.c_str());
  TestEnumFrameInterval(dev_name.c_str());
  TestFrameRate(dev_name.c_str());
  return EXIT_SUCCESS;
}
