/*
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you 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

    http://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.
*/

#include "arch.h"
#include "amcl.h"
#include "utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bls_ietf_ZZZ.h"

#define LINE_LEN 1000
//#define DEBUG


int main(int argc, char** argv)
{
    if (argc != 2) {
        printf("ERROR Not enough input arguments\n");
        exit(EXIT_FAILURE);
    }

    BIG_XXX x_re;
    BIG_XXX x_im;
    BIG_XXX y_re;
    BIG_XXX y_im;

    FP2_YYY x2;
    FP2_YYY y2;

    ECP2_ZZZ P2;
    ECP2_ZZZ P2_prime;

    // Variables for file parsing
    FILE *fp = NULL;
    char line[LINE_LEN];
    const char *linePtr = NULL;
    unsigned int l1 = 0;
    bool readLine = false;
    int lineNo = 0;

    const char *dst_str    = "dst     = ";
    const char *msg_str    = "msg     = ";
    const char *Px_re_str  = "P.x_re  = ";
    const char *Px_im_str  = "P.x_im  = ";
    const char *Py_re_str  = "P.y_re  = ";
    const char *Py_im_str  = "P.y_im  = ";

    char dst[50];
    char *msg   = NULL;
    char *Px_re = NULL;
    char *Px_im = NULL;
    char *Py_re = NULL;
    char *Py_im = NULL;

    int dst_len   = 0;
    int msg_len   = 0;
    int Px_re_len = 0;
    int Px_im_len = 0;
    int Py_re_len = 0;
    int Py_im_len = 0;

    int ret = 0;

    // Open file
    fp = fopen(argv[1], "r");
    if (fp == NULL) {
        printf("ERROR opening test vector file\n");
        exit(EXIT_FAILURE);
    }

    while (fgets(line, LINE_LEN, fp) != NULL) {
        readLine = true;
        // Read the Domain Separator Tag (DST) value
        if (!strncmp(line, dst_str, strlen(dst_str))) {
#ifdef DEBUG
            printf("line %d %s\n", lineNo,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(dst_str);
            // Allocate memory
            l1       = (unsigned int)strlen(linePtr) - 1;
            dst_len  = l1;
            for(int i = 0; i < dst_len; i++)
                dst[i] = linePtr[i];
        }

        // Read the message
        if (!strncmp(line, msg_str, strlen(msg_str))) {
#ifdef DEBUG
            printf("line %d %s\n", lineNo,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(msg_str);
            // Allocate memory
            l1       = (unsigned int)strlen(linePtr) - 1;
            msg_len  = l1;
            msg      = (char*) malloc(msg_len);
            if (msg == NULL)
                exit(EXIT_FAILURE);
            for(int i = 0; i < msg_len; i++)
                msg[i] = linePtr[i];
        }

        // Read the expected output point (real part of P_x)
        if (!strncmp(line, Px_re_str, strlen(Px_re_str))) {
#ifdef DEBUG
            printf("line %d %s\n", lineNo,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(Px_re_str);
            // Allocate memory
            l1        = (unsigned int)strlen(linePtr) - 1;
            Px_re_len = l1 / 2;
            Px_re     = (char*) malloc(Px_re_len);
            if (Px_re == NULL)
                exit(EXIT_FAILURE);
            amcl_hex2bin(linePtr, Px_re, l1);
            BIG_XXX_fromBytes(x_re, Px_re);
        }

        // Read the expected output point (imaginary part of P_x)
        if (!strncmp(line, Px_im_str, strlen(Px_im_str))) {
#ifdef DEBUG
            printf("line %d %s\n", lineNo,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(Px_im_str);
            // Allocate memory
            l1    = (unsigned int)strlen(linePtr) - 1;
            Px_im_len = l1 / 2;
            Px_im     = (char*) malloc(Px_im_len);
            if (Px_im == NULL)
                exit(EXIT_FAILURE);
            amcl_hex2bin(linePtr, Px_im, l1);
            BIG_XXX_fromBytes(x_im, Px_im);
        }

        // Read the expected output point (real part of P_y)
        if (!strncmp(line, Py_re_str, strlen(Py_re_str))) {
#ifdef DEBUG
            printf("line %d %s\n", lineNo,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(Py_re_str);
            // Allocate memory
            l1    = (unsigned int)strlen(linePtr) - 1;
            Py_re_len = l1 / 2;
            Py_re     = (char*) malloc(Py_re_len);
            if (Py_re == NULL)
                exit(EXIT_FAILURE);
            amcl_hex2bin(linePtr, Py_re, l1);
            BIG_XXX_fromBytes(y_re, Py_re);
        }

        // Read the expected output point (imaginary part of P_y)
        if (!strncmp(line, Py_im_str, strlen(Py_im_str))) {
#ifdef DEBUG
            printf("line %d %s\n", lineNo,line);
#endif
            // Find hex value in string
            linePtr = line + strlen(Py_im_str);
            // Allocate memory
            l1    = (unsigned int)strlen(linePtr) - 1;
            Py_im_len = l1 / 2;
            Py_im     = (char*) malloc(Py_im_len);
            if (Py_im == NULL)
                exit(EXIT_FAILURE);
            amcl_hex2bin(linePtr, Py_im, l1);
            octet msg_oct = {msg_len, msg_len, msg};
            octet dst_oct = {dst_len, dst_len, dst};
            BIG_XXX_fromBytes(y_im, Py_im);
            FP2_YYY_from_BIGs(&x2, x_re, x_im);
            FP2_YYY_from_BIGs(&y2, y_re, y_im);
            ECP2_ZZZ_set(&P2, &x2, &y2);

            if (strncmp(dst, "QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", sizeof(dst)) == 0) {
                ret = BLS_IETF_ZZZ_hash2curve_G2(&P2_prime, &msg_oct, &dst_oct);
                if (ECP2_ZZZ_equals(&P2, &P2_prime) == 0 || ret) { 
                    printf("TEST BLS_IETF_ZZZ_hash2curve_G2 FAILED LINE %d\n",lineNo);
                    exit(EXIT_FAILURE);
                }
            }
            else if (strncmp(dst, "QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_NU_", sizeof(dst)) == 0) {
                ret = BLS_IETF_ZZZ_encode2curve_G2(&P2_prime, &msg_oct, &dst_oct);
                if (ECP2_ZZZ_equals(&P2, &P2_prime) == 0 || ret) { 
                    printf("TEST BLS_IETF_ZZZ_encode2curve_G2 FAILED LINE %d\n",lineNo);
                    exit(EXIT_FAILURE);
                }
            }
            else {
                printf("WRONG DST - FAILED AT LINE %d\n",lineNo);
                exit(EXIT_FAILURE);
            }

            free(msg);
            free(Px_re);
            free(Px_im);
            free(Py_re);
            free(Py_im);
            msg   = NULL;
            Px_re = NULL;
            Px_im = NULL;
            Py_re = NULL;
            Py_im = NULL;
        }
        lineNo++;
    }
    fclose(fp);
    if (!readLine) {
        printf("ERROR No test vectors\n");
        exit(EXIT_FAILURE);
    }

    printf("SUCCESS TEST BLS12-381_HASH2CURVE_G2 PASSED\n");
    exit(EXIT_SUCCESS);
}
