// Copyright 2022 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ----------------

/*
print-image-metadata prints images' metadata.
*/

#include <inttypes.h>
#include <stdio.h>

// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
//
// To use that single file as a "foo.c"-like implementation, instead of a
// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
// compiling it.
#define WUFFS_IMPLEMENTATION

// Defining the WUFFS_CONFIG__STATIC_FUNCTIONS macro is optional, but when
// combined with WUFFS_IMPLEMENTATION, it demonstrates making all of Wuffs'
// functions have static storage.
//
// This can help the compiler ignore or discard unused code, which can produce
// faster compiles and smaller binaries. Other motivations are discussed in the
// "ALLOW STATIC IMPLEMENTATION" section of
// https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
#define WUFFS_CONFIG__STATIC_FUNCTIONS

// Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of
// release/c/etc.c choose which parts of Wuffs to build. That file contains the
// entire Wuffs standard library, implementing a variety of codecs and file
// formats. Without this macro definition, an optimizing compiler or linker may
// very well discard Wuffs code for unused codecs, but listing the Wuffs
// modules we use makes that process explicit. Preprocessing means that such
// code simply isn't compiled.
#define WUFFS_CONFIG__MODULES
#define WUFFS_CONFIG__MODULE__ADLER32
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__BMP
#define WUFFS_CONFIG__MODULE__CRC32
#define WUFFS_CONFIG__MODULE__DEFLATE
#define WUFFS_CONFIG__MODULE__GIF
#define WUFFS_CONFIG__MODULE__LZW
#define WUFFS_CONFIG__MODULE__NIE
#define WUFFS_CONFIG__MODULE__PNG
#define WUFFS_CONFIG__MODULE__TGA
#define WUFFS_CONFIG__MODULE__WBMP
#define WUFFS_CONFIG__MODULE__ZLIB

// If building this program in an environment that doesn't easily accommodate
// relative includes, you can use the script/inline-c-relative-includes.go
// program to generate a stand-alone C file.
#include "../release/c/wuffs-unsupported-snapshot.c"

// ----

#ifndef SRC_BUFFER_ARRAY_SIZE
#define SRC_BUFFER_ARRAY_SIZE (64 * 1024)
#endif

#ifndef META_BUFFER_ARRAY_SIZE
#define META_BUFFER_ARRAY_SIZE (64 * 1024)
#endif

#ifndef WORKBUF_ARRAY_SIZE
#define WORKBUF_ARRAY_SIZE (256 * 1024 * 1024)
#endif

#define PRINTBUF_ARRAY_SIZE 80

uint8_t g_src_buffer_array[SRC_BUFFER_ARRAY_SIZE] = {0};
uint8_t g_meta_buffer_array[META_BUFFER_ARRAY_SIZE] = {0};
uint8_t g_workbuf_array[WORKBUF_ARRAY_SIZE] = {0};

uint8_t g_printbuf_array[PRINTBUF_ARRAY_SIZE] = {0};
uint32_t g_printbuf_index = 0;

// ----

#define TRY(error_msg)         \
  do {                         \
    const char* z = error_msg; \
    if (z) {                   \
      return z;                \
    }                          \
  } while (false)

const uint8_t  //
    hexify[16] = {
        '0', '1', '2', '3', '4', '5', '6', '7',  //
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',  //
};

const uint8_t  //
    printable_ascii[256] = {
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,  //
        0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,  //
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  //
        0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,  //

        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,  //
        0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,  //
        0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,  //
        0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,  //
        0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,  //
        0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,  //
        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,  //
        0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,  //

        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //

        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
        0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,  //
};

// ----

const char*  //
read_buffer_from_file(wuffs_base__io_buffer* buf, FILE* f) {
  if (buf->meta.closed) {
    return "main: unexpected end of file";
  }
  buf->compact();
  size_t n = fread(buf->writer_pointer(), 1, buf->writer_length(), f);
  buf->meta.wi += n;
  buf->meta.closed = feof(f);
  return ferror(f) ? "main: error reading file" : nullptr;
}

void  //
print_fourcc(uint32_t fourcc) {
  printf("  %c%c%c%c\n",           //
         (0xFF & (fourcc >> 24)),  //
         (0xFF & (fourcc >> 16)),  //
         (0xFF & (fourcc >> 8)),   //
         (0xFF & (fourcc >> 0)));
}

void  //
flush_hex_dump() {
  if (g_printbuf_index == 0) {
    return;
  }
  puts(static_cast<const char*>(static_cast<const void*>(g_printbuf_array)));
  g_printbuf_index = 0;
}

void  //
print_hex_dump(const uint8_t* ptr, size_t len) {
  while (len--) {
    if (g_printbuf_index == 0) {
      const char* s =
          "    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --    "
          "----------------";
      size_t n = strlen(s);
      if ((n + 1) > PRINTBUF_ARRAY_SIZE) {
        exit(1);
      }
      memcpy(&g_printbuf_array[0], s, n + 1);
    }
    const uint8_t c = *ptr++;
    g_printbuf_array[(3 * g_printbuf_index) + 4] = hexify[c >> 4];
    g_printbuf_array[(3 * g_printbuf_index) + 5] = hexify[c & 15];
    g_printbuf_array[g_printbuf_index + 55] = printable_ascii[c];
    g_printbuf_index++;
    if (g_printbuf_index == 16) {
      puts(
          static_cast<const char*>(static_cast<const void*>(g_printbuf_array)));
      g_printbuf_index = 0;
    }
  }
}

const char*  //
print_raw_passthrough(wuffs_base__io_buffer* src,
                      FILE* f,
                      wuffs_base__range_ie_u64 r) {
  if (r.is_empty()) {
    return nullptr;
  }

  // Advance src so that its reader_position is r.min_incl.
  if (src->reader_position() > r.min_incl) {
    return "main: unsupported metadata range";
  }
  while (src->reader_position() < r.min_incl) {
    if (src->writer_position() >= r.min_incl) {
      src->meta.ri = r.min_incl - src->meta.pos;
      break;
    }
    src->meta.ri = src->meta.wi;
    TRY(read_buffer_from_file(src, f));
  }

  // Print the passthrough bytes until src's reader_position is r.max_excl.
  while (true) {
    uint64_t n0 = r.max_excl - src->reader_position();
    if (n0 == 0) {
      break;
    }
    uint64_t n1 = src->reader_length();
    uint64_t n = wuffs_base__u64__min(n0, n1);
    print_hex_dump(src->reader_pointer(), n);
    src->meta.ri += n;
  }

  return nullptr;
}

const char*  //
print_metadata(wuffs_base__image_decoder* dec,
               wuffs_base__io_buffer* src,
               FILE* f) {
  bool printed_fourcc = false;
  while (true) {
    auto meta = wuffs_base__ptr_u8__writer(&g_meta_buffer_array[0],
                                           META_BUFFER_ARRAY_SIZE);
    auto minfo = wuffs_base__empty_more_information();
    auto tmm_status = dec->tell_me_more(&meta, &minfo, src);

    if (minfo.flavor) {
      if (!printed_fourcc) {
        printed_fourcc = true;
        print_fourcc(minfo.metadata__fourcc());
      }

      switch (minfo.flavor) {
        case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH:
          TRY(print_raw_passthrough(src, f,
                                    minfo.metadata_raw_passthrough__range()));
          break;

        case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM:
          print_hex_dump(meta.reader_pointer(), meta.reader_length());
          meta.meta.ri = meta.meta.wi;
          break;

        case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED:
          switch (minfo.metadata__fourcc()) {
            case WUFFS_BASE__FOURCC__CHRM:
              for (uint32_t i = 0; i < 8; i++) {
                printf("    %" PRId32 "\n", minfo.metadata_parsed__chrm(i));
              }
              break;
            case WUFFS_BASE__FOURCC__GAMA:
              printf("    %" PRIu32 "\n", minfo.metadata_parsed__gama());
              break;
            case WUFFS_BASE__FOURCC__SRGB:
              printf("    %" PRIu32 "\n", minfo.metadata_parsed__srgb());
              break;
            default:
              return "main: unsupported metadata FourCC";
          }
          break;

        default:
          return "main: unsupported metadata flavor";
      }
    }

    if (tmm_status.is_ok()) {
      break;
    } else if (tmm_status.repr == wuffs_base__suspension__short_read) {
      TRY(read_buffer_from_file(src, f));
      continue;
    } else if (tmm_status.repr == wuffs_base__suspension__short_write) {
      continue;
    } else if (tmm_status.repr !=
               wuffs_base__suspension__even_more_information) {
      return tmm_status.message();
    }
  }
  flush_hex_dump();

  return nullptr;
}

const char*  //
handle_redirect(int32_t* out_fourcc,
                wuffs_base__image_decoder* dec,
                wuffs_base__io_buffer* src,
                FILE* f) {
  auto empty = wuffs_base__empty_io_buffer();
  auto minfo = wuffs_base__empty_more_information();
  auto tmm_status = dec->tell_me_more(&empty, &minfo, src);
  if (tmm_status.repr != NULL) {
    return tmm_status.message();
  } else if (minfo.flavor !=
             WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {
    return "main: unsupported file format";
  }
  *out_fourcc = (int32_t)(minfo.io_redirect__fourcc());
  if (*out_fourcc <= 0) {
    return "main: unsupported file format";
  }

  // Advance src so that its reader_position is r.min_incl.
  auto r = minfo.io_redirect__range();
  if (src->reader_position() > r.min_incl) {
    return "main: unsupported I/O redirect range";
  }
  while (src->reader_position() < r.min_incl) {
    if (src->writer_position() >= r.min_incl) {
      src->meta.ri = r.min_incl - src->meta.pos;
      break;
    }
    src->meta.ri = src->meta.wi;
    TRY(read_buffer_from_file(src, f));
  }
  return nullptr;
}

const char*  //
handle(const char* filename, FILE* f) {
  auto src =
      wuffs_base__ptr_u8__writer(&g_src_buffer_array[0], SRC_BUFFER_ARRAY_SIZE);
  auto work =
      wuffs_base__ptr_u8__writer(&g_workbuf_array[0], WORKBUF_ARRAY_SIZE);

  int32_t fourcc = 0;
  while (true) {
    fourcc = wuffs_base__magic_number_guess_fourcc(src.reader_slice(),
                                                   src.meta.closed);
    if (fourcc > 0) {
      break;
    } else if (fourcc == 0) {
      return "main: unrecognized file format";
    } else {
      TRY(read_buffer_from_file(&src, f));
    }
  }

  bool redirected = false;
redirect:
  do {
    print_fourcc(fourcc);
    wuffs_base__image_decoder::unique_ptr dec(nullptr, &free);
    switch (fourcc) {
      case WUFFS_BASE__FOURCC__BMP:
        dec = wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
        break;
      case WUFFS_BASE__FOURCC__GIF:
        dec = wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
        break;
      case WUFFS_BASE__FOURCC__NIE:
        dec = wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
        break;
      case WUFFS_BASE__FOURCC__PNG:
        dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
        break;
      case WUFFS_BASE__FOURCC__TGA:
        dec = wuffs_tga__decoder::alloc_as__wuffs_base__image_decoder();
        break;
      case WUFFS_BASE__FOURCC__WBMP:
        dec = wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
        break;
      default:
        return "main: unsupported file format";
    }

    dec->set_report_metadata(WUFFS_BASE__FOURCC__CHRM, true);
    dec->set_report_metadata(WUFFS_BASE__FOURCC__EXIF, true);
    dec->set_report_metadata(WUFFS_BASE__FOURCC__GAMA, true);
    dec->set_report_metadata(WUFFS_BASE__FOURCC__ICCP, true);
    dec->set_report_metadata(WUFFS_BASE__FOURCC__KVP, true);
    dec->set_report_metadata(WUFFS_BASE__FOURCC__SRGB, true);
    dec->set_report_metadata(WUFFS_BASE__FOURCC__XMP, true);

    while (true) {
      auto dfc_status = dec->decode_frame_config(NULL, &src);
      if (dfc_status.is_ok()) {
        // No-op.
      } else if (dfc_status.repr == wuffs_base__note__end_of_data) {
        break;
      } else if (dfc_status.repr == wuffs_base__note__metadata_reported) {
        TRY(print_metadata(dec.get(), &src, f));
      } else if (dfc_status.repr == wuffs_base__note__i_o_redirect) {
        if (redirected) {
          return "main: unsupported file format";
        }
        redirected = true;
        TRY(handle_redirect(&fourcc, dec.get(), &src, f));
        goto redirect;
      } else if (dfc_status.repr == wuffs_base__suspension__short_read) {
        TRY(read_buffer_from_file(&src, f));
      } else {
        return dfc_status.message();
      }
    }
  } while (false);

  return nullptr;
}

int  //
main(int argc, char** argv) {
  for (int i = 1; i < argc; i++) {
    FILE* f = fopen(argv[i], "r");
    if (!f) {
      printf("%s\n  %s\n", argv[i], strerror(errno));
      continue;
    }
    printf("%s\n", argv[i]);
    const char* err = handle(argv[i], f);
    if (err) {
      printf("  %s\n", err);
    }
    fclose(f);
  }
  return 0;
}
