/* 'checkit_tiff' is a conformance checker for baseline TIFFs
 *
 * author: Andreas Romeyke, 2015-2022
 * licensed under conditions of libtiff
 * (see http://libtiff.maptools.org/misc.html)
 *
 */

#include "check_renderer.h"
#include "ctstring.h"
#include <assert.h>

/* color definitions, using ISO 6429 as listed in 'man (5) dir_colors'
              0   to restore default color
               1   for brighter colors
               4   for underlined text
               5   for flashing text
              30   for black foreground
              31   for red foreground
              32   for green foreground
              33   for yellow (or brown) foreground
              34   for blue foreground
              35   for purple foreground
              36   for cyan foreground
              37   for white (or gray) foreground
              40   for black background
              41   for red background
              42   for green background
              43   for yellow (or brown) background
              44   for blue background
              45   for purple background
              46   for cyan background
              47   for white (or gray) background
 */
#define ANSI_NORMAL     const_str("\033[0m")
#define ANSI_BOLD       const_str("\033[1m")
#define ANSI_RED        const_str("\033[00;31m")
#define ANSI_RED_BOLD   const_str("\033[01;31m")
#define ANSI_RED_HIGH   const_str("\033[00;91m")
#define ANSI_GREEN      const_str("\033[00;32m")
#define ANSI_GREEN_BOLD const_str("\033[01;32m")
#define ANSI_RESET      const_str("\033[0m")
#define ANSI_BLACK      const_str("\033[00;30m")
#define ANSI_BLACK_BOLD const_str("\033[01;30m")
#define ANSI_BROWN      const_str("\033[00;33m")
#define ANSI_BLUE       const_str("\033[00;34m")
#define ANSI_BLUE_BOLD  const_str("\033[01;34m")
#define ANSI_PURPLE     const_str("\033[00;35m")
#define ANSI_CYAN       const_str("\033[00;36m")
#define ANSI_GREY       const_str("\033[00;37m")
#define ANSI_DARK_GREY  const_str("\033[01;30m")
#define ANSI_YELLOW     const_str("\033[01;33m")
#define ANSI_WHITE      const_str("\033[01;37m")
#define ANSI_INVERSE    const_str("\033[7m")


stringbuf_t renderer_ansi (const retmsg_t * ret) {
  assert (ret != NULL);
  stringbuf_t res = empty_stringbuf();
  const retmsg_t * startp = ret;
  rc_tristate_t rc_is_valid = rc_undef;
  // print header
  res = secstrcat_cstr(res, "\n");
  res = secstrcat_string(res, ANSI_BLACK_BOLD);
  res = secstrcat_cstr(res, "result IFD/tag \t--> rule description [; ");
  res = secstrcat_string(res, ANSI_BLUE);
  res = secstrcat_cstr(res, "expected specific values");
  res = secstrcat_string( res, ANSI_BLACK_BOLD);
  res = secstrcat_cstr(res, "] [");
  res = secstrcat_string(res, ANSI_RED);
  res = secstrcat_cstr(res, "error description");
  res = secstrcat_string(res, ANSI_BLACK_BOLD);
  res = secstrcat_cstr(res, "] ");
  res = secstrcat_string(res, ANSI_GREY);
  res = secstrcat_cstr(res, "(lineno in config)");
  res = secstrcat_string(res, ANSI_BLACK_BOLD);
  res = secstrcat_cstr(res, "\n");
  res = secstrcat_cstr( res, "----------------------------------------------------------------------------\n");
  while (NULL != startp) {
      if (startp->rm_type == rm_is_valid) {rc_is_valid = rc_valid;}
      else if (startp->rm_type == rm_error || startp->rm_type == rm_hard_error) {rc_is_valid = rc_invalid;}
      if ( check_if_quiet(startp, rc_is_valid) ) { /*do nothing */ }
      else {
          switch (startp->rm_type) {
              case rm_rule:
                  res = secstrcat_string(res, ANSI_NORMAL);
                  res = secstrcat_cstr(res, "\t--> ");
                  res = secstrcat_string(res, startp->rm_msg);
                  break;
              case rm_tag:
              case rm_mode:
                  res = secstrcat_cstr(res, "\t");
                  res = secstrcat_string(res, ANSI_BOLD);
                  res = secstrcat_string(res, startp->rm_msg);
                  break;
              case rm_value:
                  if (startp->rm_msg.len > 0) {
                      res = secstrcat_string(res, ANSI_RED_HIGH);
                      res = secstrcat_cstr(res, "; found: ");
                      res = secstrcat_string(res, startp->rm_msg);
                  }
                  break;
              case rm_expected:
                  if (startp->rm_msg.len > 0) {
                      res = secstrcat_string(res, ANSI_BLUE);
                      res = secstrcat_cstr(res, "; expected: ");
                      res = secstrcat_string(res, startp->rm_msg);
                  }
                  break;
              case rm_hard_error:
                  res = secstrcat_string(res, ANSI_RED_BOLD);
                  res = secstrcat_cstr(res, "(HE)");
                  res = secstrcat_string(res, startp->rm_msg);
                  rc_is_valid = rc_invalid;
                  break;
              case rm_error:
                  res = secstrcat_string(res, ANSI_RED);
                  res = secstrcat_cstr(res, "(EE)");
                  res = secstrcat_string(res, startp->rm_msg);
                  rc_is_valid = rc_invalid;
                  break;
              case rm_error_description:
                  res = secstrcat_string(res, ANSI_RED);
                  res = secstrcat_cstr(res, " ");
                  res = secstrcat_string(res, startp->rm_msg);
                  break;
              case rm_warning:
                  res = secstrcat_string(res, ANSI_GREY);
                  res = secstrcat_cstr(res, "(WW)");
                  res = secstrcat_string(res, startp->rm_msg);
                  rc_is_valid = rc_invalid;
                  break;
              case rm_logicalor_error:
                  res = secstrcat_string(res, ANSI_YELLOW);
                  res = secstrcat_cstr(res, "(LE)");
                  res = secstrcat_string(res, startp->rm_msg);
                  rc_is_valid = rc_invalid;
                  break;
              case rm_file:
                  res = secstrcat_cstr(res, "file: ");
                  res = secstrcat_string(res, ANSI_BLUE_BOLD);
                  res = secstrcat_string(res, startp->rm_msg);
                  res = secstrcat_string(res, ANSI_NORMAL);
                  res = secstrcat_cstr(res, "\n");
                  rc_is_valid = rc_undef;
                  break;
              case rm_lineno:
                  res = secstrcat_string(res, ANSI_GREY);
                  res = secstrcat_cstr(res, " (lineno: ");
                  res = secstrcat_string(res, startp->rm_msg);
                  res = secstrcat_cstr(res, ")");
                  break;
              case rm_endrule:
              case rm_endtiff:
                  res = secstrcat_string(res, ANSI_NORMAL);
                  res = secstrcat_cstr(res, "\n");
                  rc_is_valid = rc_undef;
                  break;
              case rm_is_valid:
                  res = secstrcat_string(res, ANSI_GREEN);
                  res = secstrcat_cstr(res, "(./)");
                  rc_is_valid = rc_valid;
                  break;
              case rm_count_valid:
                  res = secstrcat_string(res, ANSI_RESET);
                  res = secstrcat_string(res, startp->rm_msg);
                  res = secstrcat_cstr(res, "\n");
                  break;
              case rm_count_invalid:
                  res = secstrcat_string(res, ANSI_RESET);
                  res = secstrcat_string(res, startp->rm_msg);
                  res = secstrcat_cstr(res, "\n");
                  break;
              case rm_summary_valid:
                  res = secstrcat_string(res, ANSI_GREEN_BOLD);
                  res = secstrcat_cstr(res, "\n(./) ");
                  res = secstrcat_string(res, startp->rm_msg);
                  rc_is_valid = rc_undef;
                  break;
              case rm_summary_invalid:
                  res = secstrcat_string(res, ANSI_RED_BOLD);
                  res = secstrcat_cstr(res, "\n(EE)");
                  res = secstrcat_string(res, startp->rm_msg);
                  rc_is_valid = rc_undef;
                  break;
              default:
                  res = secstrcat_string(res, ANSI_NORMAL);
                  res = secstrcat_string(res, startp->rm_msg);

          }
      }
      startp = startp->next;
  }
  res=secstrcat_string( res, ANSI_NORMAL);
  res=secstrcat_cstr( res, "\n");
  return res;
}
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/
