namespace panda { namespace time {

static constexpr const size_t TZNAME_MAXLEN = 255; // max length of timezone name or POSIX rule (Europe/Moscow, ...)

static bool                get_os_localzone_name (char*);
static std::vector<string> scan_files_recursive  (string);

static bool tz_from_env (char* lzname, const char* envar) {
    const char* val = getenv(envar);
    if (val == NULL) return false;
    size_t len = std::strlen(val);
    if (len < 1 || len > TZNAME_MAXLEN) return false;
    std::strcpy(lzname, val);
    return true;
}

static string readfile (const string_view& path) {
    auto spath = string(path); // need to make path null-terminated
    FILE* fh = fopen(spath.c_str(), "rb");
    if (fh == NULL) return string();

    if (fseek(fh, 0, SEEK_END) != 0) {
        fclose(fh);
        return string();
    }

    auto size = ftell(fh);
    if (size < 0) {
        fclose(fh);
        return string();
    }

    rewind(fh);
    string ret(size);
    size_t readsize = fread(ret.buf(), sizeof(char), size, fh);
    if (readsize != (size_t)size) return string();

    fclose(fh);
    ret.length(readsize);
    return ret;
}


}}

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__linux__) || defined(__APPLE__) || defined(__OpenBSD__)
    #include "os/unix.icc"
#elif defined __VMS
    #include "os/vms.icc"
#elif defined _WIN32
    #include "os/win.icc"
#elif defined(sun) || defined(__sun)
    #include "os/solaris.icc"
#else
    #error "Current operating system is not supported"
#endif


#ifdef TZDIR
    #undef  __PTIME_TZDIR
    #define __TMP_SHIT(name) #name
    #define __PTIME_TZDIR __TMP_SHIT(TZDIR)
#endif