// Copyright 2019 The Chromium 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 "media/gpu/test/image.h"

#include <memory>

#include "base/files/file_util.h"
#include "base/hash/md5.h"
#include "base/json/json_reader.h"
#include "base/values.h"
#include "media/base/test_data_util.h"
#include "media/gpu/macros.h"

namespace media {
namespace test {

namespace {

// Resolve the specified test file path to an absolute path. The path can be
// either an absolute path, a path relative to the current directory, or a path
// relative to the test data path.
absl::optional<base::FilePath> ResolveFilePath(
    const base::FilePath& file_path) {
  base::FilePath resolved_path = file_path;

  // Try to resolve the path into an absolute path. If the path doesn't exist,
  // it might be relative to the test data dir.
  if (!resolved_path.IsAbsolute()) {
    resolved_path = base::MakeAbsoluteFilePath(
        PathExists(resolved_path)
            ? resolved_path
            : media::GetTestDataPath().Append(resolved_path));
  }

  return PathExists(resolved_path)
             ? absl::optional<base::FilePath>(resolved_path)
             : absl::nullopt;
}

// Converts the |pixel_format| string into a VideoPixelFormat.
VideoPixelFormat ConvertStringtoPixelFormat(const std::string& pixel_format) {
  if (pixel_format == "BGRA") {
    return PIXEL_FORMAT_ARGB;
  } else if (pixel_format == "I420") {
    return PIXEL_FORMAT_I420;
  } else if (pixel_format == "NV12") {
    return PIXEL_FORMAT_NV12;
  } else if (pixel_format == "YV12") {
    return PIXEL_FORMAT_YV12;
  } else if (pixel_format == "RGBA") {
    return PIXEL_FORMAT_ABGR;
  } else if (pixel_format == "I422") {
    return PIXEL_FORMAT_I422;
  } else if (pixel_format == "YUYV") {
    return PIXEL_FORMAT_YUY2;
  } else {
    VLOG(2) << pixel_format << " is not supported.";
    return PIXEL_FORMAT_UNKNOWN;
  }
}

}  // namespace

// Suffix to append to the image file path to get the metadata file path.
constexpr const base::FilePath::CharType* kMetadataSuffix =
    FILE_PATH_LITERAL(".json");

Image::Image(const base::FilePath& file_path) : file_path_(file_path) {}

Image::~Image() {}

bool Image::Load() {
  DCHECK(!file_path_.empty());
  DCHECK(!IsLoaded());

  absl::optional<base::FilePath> resolved_path = ResolveFilePath(file_path_);
  if (!resolved_path) {
    LOG(ERROR) << "Image file not found: " << file_path_;
    return false;
  }
  file_path_ = resolved_path.value();
  DVLOGF(2) << "File path: " << file_path_;

  if (!mapped_file_.Initialize(file_path_)) {
    LOG(ERROR) << "Failed to read file: " << file_path_;
    return false;
  }

  if (!LoadMetadata()) {
    LOG(ERROR) << "Failed to load metadata";
    return false;
  }

  // Verify that the image's checksum matches the checksum in the metadata.
  base::MD5Digest digest;
  base::MD5Sum(mapped_file_.data(), mapped_file_.length(), &digest);
  if (base::MD5DigestToBase16(digest) != checksum_) {
    LOG(ERROR) << "Image checksum not matching metadata";
    return false;
  }

  return true;
}

bool Image::IsLoaded() const {
  return mapped_file_.IsValid();
}

bool Image::LoadMetadata() {
  if (IsMetadataLoaded()) {
    return true;
  }

  base::FilePath json_path = file_path_.AddExtension(kMetadataSuffix);
  absl::optional<base::FilePath> resolved_path = ResolveFilePath(json_path);
  if (!resolved_path) {
    LOG(ERROR) << "Image metadata file not found: " << json_path;
    return false;
  }
  json_path = resolved_path.value();

  if (!base::PathExists(json_path)) {
    VLOGF(1) << "Image metadata file not found: " << json_path.BaseName();
    return false;
  }

  std::string json_data;
  if (!base::ReadFileToString(json_path, &json_data)) {
    VLOGF(1) << "Failed to read image metadata file: " << json_path;
    return false;
  }

  auto metadata_result =
      base::JSONReader::ReadAndReturnValueWithError(json_data);
  if (!metadata_result.value) {
    VLOGF(1) << "Failed to parse image metadata: " << json_path << ": "
             << metadata_result.error_message;
    return false;
  }
  absl::optional<base::Value> metadata = std::move(metadata_result.value);

  // Get the pixel format from the json data.
  const base::Value* pixel_format =
      metadata->FindKeyOfType("pixel_format", base::Value::Type::STRING);
  if (!pixel_format) {
    VLOGF(1) << "Key \"pixel_format\" is not found in " << json_path;
    return false;
  }
  pixel_format_ = ConvertStringtoPixelFormat(pixel_format->GetString());
  if (pixel_format_ == PIXEL_FORMAT_UNKNOWN) {
    VLOGF(1) << pixel_format->GetString() << " is not supported";
    return false;
  }

  // Get the image dimensions from the json data.
  const base::Value* width =
      metadata->FindKeyOfType("width", base::Value::Type::INTEGER);
  if (!width) {
    VLOGF(1) << "Key \"width\" is not found in " << json_path;
    return false;
  }
  const base::Value* height =
      metadata->FindKeyOfType("height", base::Value::Type::INTEGER);
  if (!height) {
    VLOGF(1) << "Key \"height\" is not found in " << json_path;
    return false;
  }
  size_ = gfx::Size(width->GetInt(), height->GetInt());

  // Try to get the visible rectangle of the image from the json data.
  // These values are not in json data if all the image data is in the visible
  // area.
  visible_rect_ = gfx::Rect(size_);
  const base::Value* visible_rect_info =
      metadata->FindKeyOfType("visible_rect", base::Value::Type::LIST);
  if (visible_rect_info) {
    base::Value::ConstListView values = visible_rect_info->GetList();
    if (values.size() != 4) {
      VLOGF(1) << "unexpected json format for visible rectangle";
      return false;
    }
    int origin_x = values[0].GetInt();
    int origin_y = values[1].GetInt();
    int visible_width = values[2].GetInt();
    int visible_height = values[3].GetInt();
    visible_rect_ =
        gfx::Rect(origin_x, origin_y, visible_width, visible_height);
  }

  // Get the image rotation info from the json data.
  const base::Value* rotation =
      metadata->FindKeyOfType("rotation", base::Value::Type::INTEGER);
  if (!rotation) {
    // Default rotation value is VIDEO_ROTATION_0
    rotation_ = VIDEO_ROTATION_0;
  } else {
    switch (rotation->GetInt()) {
      case 0:
        rotation_ = VIDEO_ROTATION_0;
        break;
      case 90:
        rotation_ = VIDEO_ROTATION_90;
        break;
      case 180:
        rotation_ = VIDEO_ROTATION_180;
        break;
      case 270:
        rotation_ = VIDEO_ROTATION_270;
        break;
      default:
        VLOGF(1) << "Invalid rotation value: " << rotation->GetInt();
        return false;
    };
  }

  // Get the image checksum from the json data.
  const base::Value* checksum =
      metadata->FindKeyOfType("checksum", base::Value::Type::STRING);
  if (!checksum) {
    VLOGF(1) << "Key \"checksum\" is not found in " << json_path;
    return false;
  }
  checksum_ = checksum->GetString();

  return true;
}

bool Image::IsMetadataLoaded() const {
  return pixel_format_ != PIXEL_FORMAT_UNKNOWN;
}

uint8_t* Image::Data() const {
  return mapped_file_.data();
}

size_t Image::DataSize() const {
  return mapped_file_.length();
}

VideoPixelFormat Image::PixelFormat() const {
  return pixel_format_;
}

const gfx::Size& Image::Size() const {
  return size_;
}

const gfx::Rect& Image::VisibleRect() const {
  return visible_rect_;
}

VideoRotation Image::Rotation() const {
  return rotation_;
}

const char* Image::Checksum() const {
  return checksum_.data();
}

}  // namespace test
}  // namespace media
