/*
 * Copyright (c) 1994, 2021 Alex Leigh, All Rights Reserved
 *
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ALEX LEIGH The copyright
 * notice above does not evidence any actual or intended publication of such
 * source code.
 *
 * Disclosure, copying, distribution, or transmission of this code without
 * express permission is prohibited.
 */

#include <stdio.h>
#include <mecha.h>

static void mecha_url_test() {
    struct mSurl url;
    char buf[1024];

    sprintf(buf, "esp://localhost:80");

    if (mFurl_parse(&url, buf) == MECHA_ERR) {
        mFlog_msg(MECHA_LOG_ERROR, "Failed to parse URL.");
        return;
    }

    mFlog_msg(MECHA_LOG_OK, "Parsed. [method: %s] [host: %s] [port: %d]", url.scheme, url.host, url.port);
}

static void mecha_net_test() {
    struct mSnet_con con;
    char *req = "GET / HTTP/1.0\r\n\r\n";
    char buf[1024];
    size_t read_bytes;
    size_t written_bytes;

    struct mSurl url;
    char urlbuf[1024];
    sprintf(urlbuf, "http://leigh-co.com:80");

    if (mFurl_parse(&url, urlbuf) == MECHA_ERR) {
        mFlog_msg(MECHA_LOG_ERROR, "Failed to parse URL.");
        return;
    }

    if (mFnet_sock_connect(&con, &url) != MECHA_OK) {
        mFlog_msg(MECHA_LOG_ERROR, "mFnet_sock_connect() failed.");
        return;
    }

    if (mFnet_write(&con, req, strlen(req), &written_bytes) == MECHA_ERR) {
        mFlog_msg(MECHA_LOG_ERROR, "Failed to write request.");
        goto done;
    }

    mFlog_msg(MECHA_LOG_OK, "Wrote request. Reading response...");
    if (mFnet_read(&con, &buf, sizeof(buf), &read_bytes) == MECHA_ERR) {
        mFlog_msg(MECHA_LOG_ERROR, "Failed to read response.");
        goto done;
    }

    if (read_bytes > 0) {
        buf[1023] = 0;
        mFlog_msg(MECHA_LOG_OK, "Response read: %s", buf);
    } else {
        mFlog_msg(MECHA_LOG_ERROR, "No response from server!");
    }

    done:
    mFnet_close(&con);
}

static void mecha_array_test() {
    struct mSda s;

    mFda_init(&s, 1, M_DA_FLAG_NULLTERMINATE);
    mFda_cat(&s, "Alex", 4);
    mFlog_msg(MECHA_LOG_OK, "String: %s", s.buf);

    mFda_cat(&s, " Leigh", 6);
    mFlog_msg(MECHA_LOG_OK, "String: %s", s.buf);

    char *p = mFda_ptr(&s, 2);
    mFlog_msg(MECHA_LOG_OK, "mFda_get: %s", p);

    mFda_free(&s, NULL);
}

static void worker(void *p) {
    struct mSthr_mutex lock;

    if (mFthr_mutex_init(&lock) != MECHA_OK) {
        perror("mutex init");
        return;
    }

    if (mFthr_mutex_lock(&lock) != MECHA_OK) {
        perror("mutex lock");
        return;
    }

    mFlog_msg(MECHA_LOG_OK, "Worker thread!");

    if (mFthr_mutex_unlock(&lock) != MECHA_OK) {
        perror("mutex unlock");
        return;
    }

    mFthr_mutex_free(&lock);

    //  mFthr_sleep(1000);
}

static void mecha_thread_test() {
    struct mSthr thread;

    if (mFthr_create(&thread, &worker) != 0) {
        mFlog_msg(MECHA_LOG_ERROR, "Thread creation failed.");
        return;
    };

    if (mFthr_join(&thread) != 0) {
        mFlog_msg(MECHA_LOG_ERROR, "Thread join failed.");
    }

    mFthr_free(&thread);
}

int main(int argc, char **argv) {
    mFlib_init();
    mecha_array_test();
    mecha_url_test();
    mecha_net_test();
    mecha_thread_test();
}