#include <stdlib.h>
#include <string.h>
#include <test.h>

extern char** environ;

TestResult test_setenv_then_getenv()
{
    clearenv();

    validate(setenv("sample", "value", 1) == 0);

    char* value = getenv("sample");
    validate(value);
    validate(!strcmp(value, "value"));

    test_success;
}

TestResult test_setenv_dont_overwrite()
{
    clearenv();

    validate(setenv("sample", "value", 1) == 0);

    char* value = getenv("sample");
    validate(value);
    validate(!strcmp(value, "value"));

    validate(setenv("sample", "other_value", 0) == 0);

    value = getenv("sample");
    validate(value);
    validate(!strcmp(value, "value"));

    test_success;
}

TestResult test_unsetenv()
{
    clearenv();

    validate(setenv("sample", "value", 1) == 0);

    char* value = getenv("sample");
    validate(value);
    validate(!strcmp(value, "value"));

    validate(unsetenv("sample") == 0);

    value = getenv("sample");
    validate(!value);

    test_success;
}

TestResult test_setenv_before_and_after_manual_environ_modification()
{
    clearenv();

    validate(setenv("sample", "value", 1) == 0);

    char* list[] = { "hello=world", NULL };
    environ = list;

    validate(setenv("other", "value", 1) == 0);

    char* value = getenv("hello");
    validate(value);
    validate(!strcmp(value, "world"));

    test_success;
}

TestResult test_putenv()
{
    clearenv();

    char lit[] = "NAME=VALUE";

    validate(putenv(lit) == 0);

    char* value = getenv("NAME");
    validate(value && !strcmp(value, "VALUE"));

    lit[0] = 'F';

    value = getenv("NAME");
    validate(!value);

    value = getenv("FAME");
    validate(value && !strcmp(value, "VALUE"));

    validate(unsetenv("FAME") == 0);

    value = getenv("FAME");
    validate(!value);

    validate(!strcmp(lit, "FAME=VALUE"));

    test_success;
}

Result<void> test_main()
{
    test_prelude;

    run_test(test_setenv_then_getenv);
    run_test(test_setenv_dont_overwrite);
    run_test(test_unsetenv);
    run_test(test_setenv_before_and_after_manual_environ_modification);
    run_test(test_putenv);

    return {};
}