/* '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.h"
#include "check_helper.h"
#include <assert.h>
#include <stdio.h>

#include "ctstring.h"

/** check if date / time values are within correct ranges
 * @param year year
 * @param month month
 * @param day day
 * @param hour hour
 * @param min min
 * @param sec sec
 * @return 0 if success, otherwise -1
 */
static int test_plausibility (const int * year, const int * month, const int * day, const int * hour, const int * min, const int * sec) {
#ifdef DEBUG
  printf ("found: y=%d m=%d d=%d h=%d m=%d s=%d\n", *year, *month, *day, *hour, *min, *sec);
#endif
  if (
      1500 < *year &&
      2100 > *year &&
      0 < *month &&
      13 > *month &&
      0 < *day &&
      32 > *day &&
      0 <= *hour &&
      24 > *hour &&
      0 <= *min &&
      60 > *min &&
      0 <= *sec &&
      60 > *sec
     ) {
    return 0;
  } else {
    return -1;
  }
}


ret_t check_datetime(ctiff_t * ctif ) {
  GET_EMPTY_RET(ret);
  TIFP_CHECK( ctif, ret);
  EXIST_TAG(ctif,TIFFTAG_DATETIME,ret);

  /* find date-tag and fix it */
  TIFFDataType datatype =  TIFFGetRawTagType( ctif, ctif->ifd0, TIFFTAG_DATETIME );
  if (datatype != TIFF_ASCII) {
    ret= set_value_found_ret_formatted(&ret, "type:%s", TIFFTypeName(datatype));
    ret.returncode = tagerror_unexpected_type_found;
    return ret;
  }
  uint32 count=0;
  char *datetime=NULL;
  ret = TIFFGetFieldASCII(ctif, ctif->ifd0, TIFFTAG_DATETIME, &datetime, &count);
  if (ret.returncode != is_valid) return ret;

  // printf("DATETIME='%s'\n", datetime);
    int day=0;
    int month=0;
    int year=0;
    int hour=0;
    int min=0;
    int sec=0;
    unsigned int r = 0;
    for (uint32 i=0; i<count; i++) {
        if ((datetime[i] == '\0') && (i != 19)) { /* \0 at 20th byte  allowed */
          r = i+1;
          break;
        }
    }
#ifdef DEBUG
    printf(" count=%u\n\n", count);
#endif
    ret = set_expected_value_formatted(&ret, "date in form 'YYYY:MM:DD hh:mm:ss");
    ret = set_value_found_ret_with_returncode(&ret, str(datetime), should_not_occur);
    if (0 == r) {
      if (6 == sscanf(datetime, "%04d:%02d:%02d%02d:%02d:%02d", &year, &month, &day, &hour, &min, &sec)) {
        if (0 == test_plausibility(&year, &month, &day, &hour, &min, &sec)) {
          ret.returncode= is_valid;
        } else {
          ret.returncode = tagerror_datetime_not_plausible;
        }
      } else {
        ret.returncode = tagerror_datetime_wrong_format;
      }
    } else {
        ret.returncode = tagerror_datetime_wrong_size;
    }
    free(datetime);
    assert( ret.returncode != should_not_occur);
    return ret;
}

/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/
