#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

#include "crypt.h"
#include "utils.h"
#include "i2c.h"

// text to encrypt and send (TODO: ideally it would be static const)
uint8_t in[] = "HELLO WORLD!!!";

// This test shows that connection is indeed persistent as many
// operations can be done after connection.
void test(int device_id) {
    con_t ctx = {0};
    // received data will be stored here
    uint8_t out[MAX_BUFFER_SIZE]={0};

    // test i2c_is_connected
    assert(i2c_is_connected(&ctx)==0);
    assert(i2c_dev_open(&ctx, device_id, 0x03) == 1);
    assert(i2c_is_connected(&ctx)==1);

    // test data sending
    buf_t tmp = {
        .b  = in,
        .sz = sizeof(in)
    };

    for (size_t i=0; i<10; i++)
        assert(i2c_send(&ctx, &tmp) == 1);

    // test data receiving
    tmp.b  = out;
    for (size_t i=0; i<1; i++)
        tmp.sz = sizeof(out)+TAG_LEN;
        assert(i2c_recv(&ctx, &tmp) == 1);

    // test i2c_is_connected again
    assert(i2c_is_connected(&ctx)==1);
    i2c_dev_close(&ctx);
    assert(i2c_is_connected(&ctx)==0);
    // Check if same data was received and sent
    assert(memcmp(in, tmp.b, tmp.sz) == 0);
}

void test_send(int device_id) {
    con_t ctx = {0};
    if (!i2c_dev_open(&ctx, device_id, 0x03)) {
        PANIC("Can't connect to device %d and slave on 0x03", device_id);
    }
    // test data sending
    buf_t tmp = {
        .b  = in,
        .sz = sizeof(in)
    };

    if (!i2c_send(&ctx, &tmp)) {
        PANIC("Error occured when sending data");
    }
    i2c_dev_close(&ctx);
}

void test_receive(int device_id) {
    con_t ctx = {0};
    // received data will be stored here
    uint8_t out[MAX_BUFFER_SIZE]={0};

    if (!i2c_dev_open(&ctx, device_id, 0x03)) {
        PANIC("Can't connect to device %d and slave on 0x03", device_id);
    }
    // test data sending
    buf_t tmp = {
        .b  = in,
        .sz = sizeof(in)
    };

    // test data receiving
    tmp.b  = out;
    tmp.sz = sizeof(in)+TAG_LEN;
    if (!i2c_recv(&ctx, &tmp)) {
        PANIC("Error occured when receiving data");
    }
    i2c_dev_close(&ctx);

    printf("RECEIVED DATA:\n%s\n", tmp.b);
}

void usage() {
    printf("Usage: ./bin/main [-s|-r|-t] device\n");
    exit(EXIT_FAILURE);
}

int main(int argc, char* argv[]) {
    if (argc != 3) {
        usage();
    }

    if (!memcmp("-t", argv[1], 2)) {
        test(atoi(argv[2]));
    }

    else if (!memcmp("-s", argv[1], 2)) {
        test_send(atoi(argv[2]));
    }

    else if (!memcmp("-r", argv[1], 2)) {
        test_receive(atoi(argv[2]));
    }
    else {
        usage();
    }
    return 0;
}