/*
 **********************************************************************
 * Copyright (C) Miroslav Lichvar  2020
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************
 */

#include <config.h>
#include "test.h"

#ifdef FEAT_NTS

#include <nts_ke_session.c>

#include <local.h>
#include <socket.h>
#include <sched.h>

static NKSN_Instance client, server;
static unsigned char record[NKE_MAX_MESSAGE_LENGTH];
static int record_length, critical, type_start, records;
static int request_received;
static int response_received;

static void
send_message(NKSN_Instance inst)
{
  int i;

  record_length = random() % (NKE_MAX_MESSAGE_LENGTH - 4 + 1);
  for (i = 0; i < record_length; i++)
    record[i] = random() % 256;
  critical = random() % 2;
  type_start = random() % 30000 + 1;
  assert(sizeof (struct RecordHeader) == 4);
  records = random() % ((NKE_MAX_MESSAGE_LENGTH - 4) / (4 + record_length) + 1);

  DEBUG_LOG("critical=%d type_start=%d records=%d*%d",
            critical, type_start, records, record_length);

  NKSN_BeginMessage(inst);

  TEST_CHECK(check_message_format(&inst->message, 0));
  TEST_CHECK(!check_message_format(&inst->message, 1));

  TEST_CHECK(!NKSN_AddRecord(inst, 0, 1, record, NKE_MAX_MESSAGE_LENGTH - 4 + 1));

  TEST_CHECK(check_message_format(&inst->message, 0));
  TEST_CHECK(!check_message_format(&inst->message, 1));

  for (i = 0; i < records; i++) {
    TEST_CHECK(NKSN_AddRecord(inst, critical, type_start + i, record, record_length));
    TEST_CHECK(!NKSN_AddRecord(inst, 0, 1, &record,
                               NKE_MAX_MESSAGE_LENGTH - inst->message.length - 4 + 1));

    TEST_CHECK(check_message_format(&inst->message, 0));
    TEST_CHECK(!check_message_format(&inst->message, 1));
  }

  TEST_CHECK(NKSN_EndMessage(inst));

  TEST_CHECK(check_message_format(&inst->message, 0));
  TEST_CHECK(check_message_format(&inst->message, 1));
}

static void
verify_message(NKSN_Instance inst)
{
  unsigned char buffer[NKE_MAX_MESSAGE_LENGTH];
  int i, c, t, length, buffer_length, msg_length, prev_parsed;
  NKE_Key c2s, s2c;

  for (i = 0; i < records; i++) {
    memset(buffer, 0, sizeof (buffer));
    buffer_length = random() % (record_length + 1);
    assert(buffer_length <= sizeof (buffer));

    prev_parsed = inst->message.parsed;
    msg_length = inst->message.length;

    TEST_CHECK(NKSN_GetRecord(inst, &c, &t, &length, buffer, buffer_length));
    TEST_CHECK(c == critical);
    TEST_CHECK(t == type_start + i);
    TEST_CHECK(length == record_length);
    TEST_CHECK(memcmp(record, buffer, buffer_length) == 0);
    if (buffer_length < record_length)
      TEST_CHECK(buffer[buffer_length] == 0);

    inst->message.length = inst->message.parsed - 1;
    inst->message.parsed = prev_parsed;
    TEST_CHECK(!get_record(&inst->message, NULL, NULL, NULL, buffer, buffer_length));
    TEST_CHECK(inst->message.parsed == prev_parsed);
    inst->message.length = msg_length;
    if (msg_length < 0x8000) {
      inst->message.data[prev_parsed + 2] ^= 0x80;
      TEST_CHECK(!get_record(&inst->message, NULL, NULL, NULL, buffer, buffer_length));
      TEST_CHECK(inst->message.parsed == prev_parsed);
      inst->message.data[prev_parsed + 2] ^= 0x80;
    }
    TEST_CHECK(get_record(&inst->message, NULL, NULL, NULL, buffer, buffer_length));
    TEST_CHECK(inst->message.parsed > prev_parsed);
  }

  TEST_CHECK(!NKSN_GetRecord(inst, &critical, &t, &length, buffer, sizeof (buffer)));

  TEST_CHECK(NKSN_GetKeys(inst, AEAD_AES_SIV_CMAC_256, &c2s, &s2c));
  TEST_CHECK(c2s.length == SIV_GetKeyLength(AEAD_AES_SIV_CMAC_256));
  TEST_CHECK(s2c.length == SIV_GetKeyLength(AEAD_AES_SIV_CMAC_256));
}

static int
handle_request(void *arg)
{
  NKSN_Instance server = arg;

  verify_message(server);

  request_received = 1;

  send_message(server);

  return 1;
}

static int
handle_response(void *arg)
{
  NKSN_Instance client = arg;

  response_received = 1;

  verify_message(client);

  return 1;
}

static void
check_finished(void *arg)
{
  DEBUG_LOG("checking for stopped sessions");
  if (!NKSN_IsStopped(server) || !NKSN_IsStopped(client)) {
    SCH_AddTimeoutByDelay(0.001, check_finished, NULL);
    return;
  }

  SCH_QuitProgram();
}

void
test_unit(void)
{
  NKSN_Credentials client_cred, server_cred;
  const char *cert, *key;
  int sock_fds[2], i;
  uint32_t cert_id;

  LCL_Initialise();
  TST_RegisterDummyDrivers();

  cert = "nts_ke.crt";
  key = "nts_ke.key";
  cert_id = 0;

  for (i = 0; i < 50; i++) {
    SCH_Initialise();

    server = NKSN_CreateInstance(1, NULL, handle_request, NULL);
    client = NKSN_CreateInstance(0, "test", handle_response, NULL);

    server_cred = NKSN_CreateServerCertCredentials(&cert, &key, 1);
    client_cred = NKSN_CreateClientCertCredentials(&cert, &cert_id, 1, 0);

    TEST_CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds) == 0);
    TEST_CHECK(fcntl(sock_fds[0], F_SETFL, O_NONBLOCK) == 0);
    TEST_CHECK(fcntl(sock_fds[1], F_SETFL, O_NONBLOCK) == 0);

    TEST_CHECK(NKSN_StartSession(server, sock_fds[0], "client", server_cred, 4.0));
    TEST_CHECK(NKSN_StartSession(client, sock_fds[1], "server", client_cred, 4.0));

    send_message(client);

    request_received = response_received = 0;

    check_finished(NULL);

    SCH_MainLoop();

    TEST_CHECK(NKSN_IsStopped(server));
    TEST_CHECK(NKSN_IsStopped(client));

    TEST_CHECK(request_received);
    TEST_CHECK(response_received);

    NKSN_DestroyInstance(server);
    NKSN_DestroyInstance(client);

    NKSN_DestroyCertCredentials(server_cred);
    NKSN_DestroyCertCredentials(client_cred);

    SCH_Finalise();
  }

  LCL_Finalise();
}
#else
void
test_unit(void)
{
  TEST_REQUIRE(0);
}
#endif
