/* '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)
 *
 */

#ifdef HAVE_IccProfLib
#include "validate_icc.h"
#include "strcopy.h"
#include <IccProfile.h>
#include <IccTag.h>
#include <IccIO.h>
#include <IccUtil.h>
#include <regex>
#include <algorithm>
#include <string>
#include <iostream>

icc_returncode_t validate_icc_with_IccProfLib(unsigned long iccsize, const char* iccdata, unsigned long errsize, char * errorneous_value) {
    CIccMemIO pIO;
    pIO.Attach((icUInt8Number *) iccdata, iccsize, false);
    CIccProfile pIcc;
    // read and parse
    std::string sReport;
    // validate ICC profile
    auto nStatus = pIcc.ReadValidate(&pIO, sReport);
    // to handle own rules, only the sReport is used

#ifdef USE_WARNING
    std::cout << " has Status "<< nStatus << std::endl;
    std::cout << sReport << std::endl;
#endif
    // remove all carriage returns
    sReport.erase(std::remove(sReport.begin(), sReport.end(), '\r'),sReport.end());
    cit_strcopy(errorneous_value, errsize, sReport.c_str(), sReport.size());
    //strncpy(errorneous_value, sReport.c_str(), errsize);
    static auto regex_unregcmm_warning = std::regex("^Warning.* Unknown '.*'.*: Unregistered CMM signature");
    static auto regex_7bit_warning = std::regex("^Warning.* Text does not contain just 7-bit data");
    static auto regex_generic_warning = std::regex("Warning(.*)");
    static auto regex_scriptcode_error = std::regex("NonCompliant.* profileDescriptionTag: - ScriptCode must contain 67 bytes.");
    static auto regex_generic_error = std::regex("NonCompliant(.*)");
    /* errors handling */
    if (std::regex_match(sReport,
                         regex_scriptcode_error)) {
        return icc_error_profile_description_tag;
    }
    if (std::smatch sm; nStatus == 2 || std::regex_match(sReport, sm, regex_generic_error)) {
#ifdef DEBUG
        std::cout << "the matches are: " << std::endl;
        for (unsigned i = 0; i < sm.size(); ++i) {
            std::cout << "[" << sm[i] << "] ";
        }
        std::cout << std::endl;
#endif
        return icc_hard_error_found_by_IccProfLib;
    }
#ifdef WITH_STRONG_ICC
    /* warnings handling */
    if (std::regex_match(sReport, regex_unregcmm_warning)) {
        return icc_error_preferredcmmtype;
    }
    if (std::regex_match(sReport, regex_7bit_warning)) {
        return icc_error_not_ascii;
    }
    if (nStatus == 1 || std::regex_match(sReport, sm, regex_generic_warning)) {
#ifdef DEBUG
        std::cout << "the matches are: " << std::endl;
        for (unsigned i = 0; i < sm.size(); ++i) {
            std::cout << "[" << sm[i] << "] ";
        }
        std::cout << std::endl;
#endif
        return icc_error_found_by_IccProfLib;
    }
#endif
    return icc_is_valid;
}
#endif
