// Copyright 2023 Google LLC
// SPDX-License-Identifier: BSD-2-Clause

#include "printmetadata_command.h"

#include <cassert>
#include <iomanip>

#include "avif/avif_cxx.h"

namespace avif {

namespace {
template <typename T>
std::string FormatFraction(T fraction) {
  std::stringstream stream;
  stream << (fraction->d != 0 ? (double)fraction->n / fraction->d : 0)
         << " (as fraction: " << fraction->n << "/" << fraction->d << ")";
  return stream.str();
}

template <typename T>
std::string FormatFractions(const T fractions[3]) {
  std::stringstream stream;
  const int w = 40;
  stream << "R " << std::left << std::setw(w) << FormatFraction(fractions)
         << " G " << std::left << std::setw(w) << FormatFraction(fractions)
         << " B " << std::left << std::setw(w) << FormatFraction(fractions);
  return stream.str();
}
}  // namespace

PrintMetadataCommand::PrintMetadataCommand()
    : ProgramCommand("printmetadata",
                     "Print the metadata of the gain map of an AVIF file") {
  argparse_.add_argument(arg_input_filename_, "input_filename");
  arg_jobs_.Init(argparse_);
}

avifResult PrintMetadataCommand::Run() {
  DecoderPtr decoder(avifDecoderCreate());
  if (decoder == nullptr) {
    return AVIF_RESULT_OUT_OF_MEMORY;
  }
  decoder->maxThreads = arg_jobs_.jobs.value();

  avifResult result =
      avifDecoderSetIOFile(decoder.get(), arg_input_filename_.value().c_str());
  if (result != AVIF_RESULT_OK) {
    std::cerr << "Cannot open file for read: " << arg_input_filename_ << "\n";
    return result;
  }
  result = avifDecoderParse(decoder.get());
  if (result != AVIF_RESULT_OK) {
    std::cerr << "Failed to parse image: " << avifResultToString(result) << " ("
              << decoder->diag.error << ")\n";
    return result;
  }
  if (decoder->image->gainMap == nullptr) {
    std::cerr << "Input image " << arg_input_filename_
              << " does not contain a gain map\n";
    return AVIF_RESULT_INVALID_ARGUMENT;
  }
  assert(decoder->image->gainMap);

  const avifGainMap& gainMap = *decoder->image->gainMap;
  const int w = 20;
  std::cout << " * " << std::left << std::setw(w)
            << "Base headroom: " << FormatFraction(&gainMap.baseHdrHeadroom)
            << "\n";
  std::cout << " * " << std::left << std::setw(w) << "Alternate headroom: "
            << FormatFraction(&gainMap.alternateHdrHeadroom) << "\n";
  std::cout << " * " << std::left << std::setw(w)
            << "Gain Map Min: " << FormatFractions(gainMap.gainMapMin) << "\n";
  std::cout << " * " << std::left << std::setw(w)
            << "Gain Map Max: " << FormatFractions(gainMap.gainMapMax) << "\n";
  std::cout << " * " << std::left << std::setw(w)
            << "Base Offset: " << FormatFractions(gainMap.baseOffset) << "\n";
  std::cout << " * " << std::left << std::setw(w)
            << "Alternate Offset: " << FormatFractions(gainMap.alternateOffset)
            << "\n";
  std::cout << " * " << std::left << std::setw(w)
            << "Gain Map Gamma: " << FormatFractions(gainMap.gainMapGamma)
            << "\n";
  std::cout << " * " << std::left << std::setw(w) << "Use Base Color Space: "
            << (gainMap.useBaseColorSpace ? "True" : "False") << "\n";

  return AVIF_RESULT_OK;
}

}  // namespace avif
