/***************************************************************************
 *   crwx-ng                                                               *
 *   Copyright (C) 2007 Vadim Lopatin <coolreader.org@gmail.com>           *
 *   Copyright (C) 2020,2023,2024 Aleksey Chernov <valexlin@gmail.com>     *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU General Public License           *
 *   as published by the Free Software Foundation; either version 2        *
 *   of the License, or (at your option) any later version.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the Free Software           *
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,            *
 *   MA 02110-1301, USA.                                                   *
 ***************************************************************************/

#include "utils.h"

#include <wx/stdpaths.h>
#include <wx/filename.h>
#include <wx/utils.h>

#include <lvstreamutils.h>

lString32 wx2cr(wxString str) {
    return Utf8ToUnicode(str.utf8_str().data());
}

wxString cr2wx(lString32 str) {
    lString8 s8 = UnicodeToUtf8(str);
    return wxString(s8.c_str(), wxConvUTF8);
}

static lString32 s_mainDataDir;
static lString32 s_engineDataDir;
static lString32 s_exeDir;
static lString32 s_configDir;
static lString32 s_engineCacheDir;

lString32 getMainDataDir() {
    if (s_mainDataDir.empty()) {
#if MACOS == 1
        // TODO: test this
        wxString path = wxFileName(wxStandardPaths::Get().GetExecutablePath())
                                .GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
        path += "/../Resources/";
        wxFileName fileName(path);
        fileName.MakeAbsolute();
        s_engineDataDir = wx2cr(fileName.GetFullPath());
#elif defined(WIN32)
        // TODO: test this
        wxFileName fileName(wxStandardPaths::Get().GetExecutablePath());
        s_engineDataDir = wx2cr(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
#else
        s_mainDataDir = lString32(CRUI_DATA_DIR);
#endif
    }
    return s_mainDataDir;
}

lString32 getEngineDataDir() {
    if (s_engineDataDir.empty()) {
#if MACOS == 1
        // TODO: test this
        wxString path = wxFileName(wxStandardPaths::Get().GetExecutablePath())
                                .GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
        path += "/../Resources/";
        wxFileName fileName(path);
        fileName.MakeAbsolute();
        s_engineDataDir = wx2cr(fileName.GetFullPath());
#elif defined(WIN32)
        // TODO: test this
        wxFileName fileName(wxStandardPaths::Get().GetExecutablePath());
        s_engineDataDir = wx2cr(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
#else
        s_engineDataDir = lString32(CRE_NG_DATADIR);
#endif
    }
    return s_engineDataDir;
}

lString32 getExeDir() {
    if (s_exeDir.empty()) {
        wxFileName fileName(wxStandardPaths::Get().GetExecutablePath());
        s_exeDir = wx2cr(fileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
    }
    return s_exeDir;
}

lString32 getConfigDir() {
    if (s_configDir.empty()) {
#if MACOS == 1
        // TODO: test this
        s_configDir = wx2cr(wxGetHomeDir() + "/Library/crui/");
#elif defined(WIN32)
        // TODO: test this
        // ~/crui/
        s_configDir = wx2cr(wxGetHomeDir() + "/crui/");
#else
        // Use $XDG_CONFIG_HOME environment variable if set or '~/.config' then concatenate '/crui/'
        wxString xdg_config_home;
        wxGetEnv("XDG_CONFIG_HOME", &xdg_config_home);
        if (xdg_config_home.IsEmpty())
            xdg_config_home = wxGetHomeDir() + "/.config";
        wxString path = xdg_config_home + "/crui/";
        s_configDir = wx2cr(path);
#endif
    }
    return s_configDir;
}

lString32 getEngineCacheDir() {
    if (s_engineCacheDir.empty()) {
#if MACOS == 1
        // TODO: test this
        wxString path = wxGetHomeDir() + "/Library/crui/cache/";
        s_engineCacheDir = wx2cr(path);
#elif defined(WIN32)
        // TODO: test this
        // ~/crui/cache
        s_engineCacheDir = wx2cr(wxGetHomeDir() + "/crui/cache/");
#else
        // Use $XDG_CACHE_HOME environment variable if set or '~/.cache' then concatenate '/crui/'
        wxString xdg_cache_home;
        wxGetEnv("XDG_CACHE_HOME", &xdg_cache_home);
        if (xdg_cache_home.IsEmpty())
            xdg_cache_home = wxGetHomeDir() + "/.cache";
        wxString path = xdg_cache_home + "/crui/";
        s_engineCacheDir = wx2cr(path);
#endif
    }
    return s_engineCacheDir;
}

CRPropRef addProperties(CRPropRef dest, CRPropRef source) {
    for (int i = 0; i < source->getCount(); i++) {
        dest->setStringDef(source->getName(i), source->getValue(i));
    }
    return dest;
}
