#include <unistd.h>
#include <regex.h>

#define __PTIME_TZDIR "/usr/share/zoneinfo"

namespace panda { namespace time {

static inline bool _from_etc_localtime (char* lzname) {
    if (access("/etc/localtime", R_OK) != 0) return false;
    strcpy(lzname, ":/etc/localtime");
    return true;
}

static inline bool _from_usr_local_etc_localtime (char* lzname) {
    if (access("/usr/local/etc/localtime", R_OK) != 0) return false;
    strcpy(lzname, ":/usr/local/etc/localtime");
    return true;
}

static inline bool _from_regex (char* lzname, const char* filename, regex_t* pattern, int nmatch) {
    string content = readfile(filename);
    if (!content) return false;
    
    // null-terminate
    content.reserve(content.length()+1);
    content[content.length()] = 0;
    
    regmatch_t m[10];
    if (regexec(pattern, content.data(), 10, m, 0) != 0) return false; // no match
    
    size_t len = m[nmatch].rm_eo - m[nmatch].rm_so;
    if (len < 1 || len > TZNAME_MAXLEN) return false;
    
    strncpy(lzname, content.data() + m[nmatch].rm_so, len);
    lzname[len] = '\0';
    return true;
}

static inline bool _from_etc_timezone (char* lzname) {
    regex_t pattern;
    int err = regcomp(&pattern, "([^[:space:]]+)", REG_EXTENDED|REG_NEWLINE);
    assert(err == 0);
    return _from_regex(lzname, "/etc/timezone", &pattern, 1);
}

static inline bool _from_etc_TIMEZONE (char* lzname) {
    regex_t pattern;
    int err = regcomp(&pattern, "^[[:space:]]*TZ[[:space:]]*=[[:space:]]*([^[:space:]]+)", REG_EXTENDED|REG_NEWLINE);
    assert(err == 0);
    return _from_regex(lzname, "/etc/TIMEZONE", &pattern, 1);
}

static inline bool _from_etc_sysconfig_clock (char* lzname) {
    regex_t pattern;
    int err = regcomp(&pattern, "^[[:space:]]*(TIME)?ZONE[[:space:]]*=[[:space:]]*\"([^\"]+)\"", REG_EXTENDED|REG_NEWLINE);
    assert(err == 0);
    return _from_regex(lzname, "/etc/sysconfig/clock", &pattern, 2);
}

static inline bool _from_etc_default_init (char* lzname) {
    regex_t pattern;
    int err = regcomp(&pattern, "^[[:space:]]*TZ[[:space:]]*=[[:space:]]*([^[:space:]]+)", REG_EXTENDED|REG_NEWLINE);
    assert(err == 0);
    return _from_regex(lzname, "/etc/default/init", &pattern, 1);
}

static bool get_os_localzone_name (char* lzname) {
    if (
        _from_etc_localtime(lzname)           ||
        _from_usr_local_etc_localtime(lzname) ||
        _from_etc_timezone(lzname)            ||
        _from_etc_TIMEZONE(lzname)            ||
        _from_etc_sysconfig_clock(lzname)     ||
        _from_etc_default_init(lzname)
    ) return true;
    return false;
}

}}

#include "scan_files_unix.icc"