#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include "ScriptOptions.hpp"
#include "Utilities/StringUtils.hpp"
#include "Script.hpp"

Porygon::ScriptOptions Porygon::ScriptOptions::DefaultScriptOptions;

std::streambuf* Porygon::ScriptOptions::_printBuffer = std::cout.rdbuf();
std::ostream* Porygon::ScriptOptions::_printStream = new std::ostream(Porygon::ScriptOptions::_printBuffer);

void Porygon::ScriptOptions::DefaultPrint(const char16_t *s) {
    Porygon::ScriptOptions::GetDefaultScriptOptions()->GetPrintStream() << Porygon::Utilities::StringUtils::FromUTF8(s) << std::endl;
}

bool Porygon::ScriptOptions::DefaultModuleExists(const std::string& moduleName) {
    struct stat buffer;
    return (stat (moduleName.c_str(), &buffer) == 0);
}

Porygon::Script *Porygon::ScriptOptions::DefaultResolveModule(const std::string& moduleName) {
    auto stream = std::ifstream(moduleName);
    std::basic_stringstream<char16_t> stringStream;
    stringStream << stream.rdbuf();
    auto str = std::u16string(stringStream.str());
    return Porygon::Script::Create(str);
}

extern "C"{
    void SetDefaultPrintFunc(void (*func)(const char16_t*)){
        Porygon::ScriptOptions::GetDefaultScriptOptions()->SetPrintFunc(func);
    }
}