/**
 *  Copyright 2022 Rive Inc.
 */

#ifdef TESTING
#else

#include "imagediff_arguments.hpp"
#include "image_cmp.hpp"
#include "SkImage.h"
#include "SkData.h"
#include "SkPixmap.h"
#include "common/write_png_file.hpp"

#include <assert.h>
#include <string>
#include <stdio.h>

class WFile
{
  FILE* m_File = nullptr;
  bool m_DoClose;

public:
  WFile(FILE* existingFile) : m_File(existingFile) { m_DoClose = false; }

  WFile(const char path[], const char mode[]) : m_File(fopen(path, mode))
  {
    m_DoClose = true;
  }

  ~WFile() { this->close(); }

  bool isOpen() const { return m_File != nullptr; }

  bool open(const char path[], const char mode[])
  {
    this->close();
    m_File = fopen(path, mode);
    return m_File != nullptr;
  }

  void close()
  {
    if (m_DoClose && m_File)
    {
      fclose(m_File);
    }
    m_File = nullptr;
  }

  void write(const void* data, size_t length)
  {
    assert(m_File);
    fwrite(data, 1, length, m_File);
  }

  void write(const std::string& str) { this->write(str.c_str(), str.size()); }

  void writeln(const std::string& str)
  {
    this->write(str);
    this->write("\n");
  }
};

static sk_sp<SkImage> file_to_image(const char path[])
{
  auto data = SkData::MakeFromFileName(path);
  if (!data)
  {
    return nullptr;
  }
  auto img = SkImage::MakeFromEncoded(data);
  if (img)
  {
    img = img->makeRasterImage();
  }
  return img;
}

static void write_file(
    const char dir[],
    const char name[],
    const char suffix[],
    sk_sp<SkImage> img)
{
  auto path = std::string(dir) + std::string("/") + std::string(name) +
              std::string(suffix);

  SkColorInfo colorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
  std::vector<uint8_t> pixels(img->height() * img->width() * 4);
  img->readPixels(
      nullptr,
      SkPixmap(
          SkImageInfo::Make({img->width(), img->height()}, colorInfo),
          pixels.data(),
          img->width() * 4),
      0,
      0);

  //    printf("creating %s\n", path.c_str());
  WritePNGFile(
      pixels.data(),
      img->width(),
      img->height(),
      false,
      path.c_str(),
      PNGCompression::fast_rle);
}

void image_diff(
    const char name[],
    const char pathA[],
    const char pathB[],
    const char statusPath[],
    const char diffDir[])
{
  WFile status = statusPath && statusPath[0] ? WFile(statusPath, "a")
                                             : WFile(stdout);
  if (!status.isOpen())
  {
    throw "failed to open status file";
  }

  status.write(std::string(name) + "\t");

  auto imgA = file_to_image(pathA);
  auto imgB = file_to_image(pathB);
  if (!imgA || !imgB)
  {
    status.writeln("failed");
    return;
  }

  const auto cmp = image_cmp(imgA, imgB);
  if (!cmp.images_loaded)
  {
    status.writeln("failed");
    return;
  }

  if (cmp.identical())
  {
    status.writeln("identical");
    return;
  }

  if (!cmp.dimensions_equal)
  {
    status.writeln("sizemismatch");
    return;
  }

  status.writeln(
      std::to_string(cmp.max_component_diff) + '\t' +
      std::to_string(cmp.ave_component_diff) + '\t' +
      std::to_string(cmp.pixel_diffcount) + '\t' +
      std::to_string(imgA->height() * imgA->width()));

  if (diffDir && diffDir[0])
  {
    auto diff0 = make_diff_image(imgA, imgB, compute_diff0);
    auto diff1 = make_diff_image(imgA, imgB, compute_diff1);

    write_file(diffDir, name, ".diff0.png", diff0);
    write_file(diffDir, name, ".diff1.png", diff1);
  }
}

int main(int argc, const char* argv[])
{
  try
  {
    ImageDiffArguments args(argc, argv);

    image_diff(
        args.name().c_str(),
        args.golden().c_str(),
        args.candidate().c_str(),
        args.status().c_str(),
        args.output().c_str());
  }
  catch (const args::Completion& e)
  {
    return 0;
  }
  catch (const args::Help&)
  {
    return 0;
  }
  catch (const args::ParseError& e)
  {
    return 1;
  }
  catch (args::ValidationError e)
  {
    return 1;
  }

  return 0;
}

#endif
