/*
 * updaterconfig.h by Matthias Braun <matze@braunis.de>
 *
 * Copyright (C) 2002 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) 
 *
 *
 * 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 (version 2 of the License)
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */
#ifndef __UPDATERCONFIG_H__
#define __UPDATERCONFIG_H__

#include <csutil/csstring.h>
#include <csutil/array.h>
#include <csutil/parray.h>
#include <iutil/document.h>

namespace updater
{

    class Config;
class Mirror
{
public:
    Mirror() { working = true; }     

    const char* GetName() { return name; }
    const char* GetBaseURL() { return baseURL; }
    const char* GetRepository() { return repositoryFile; }
    const char* GetVersion() { return versionFile; }
    const char* GetFilesDirectory() { return filesDirectory; }
    const char* GetPassphrase() { return passphrase; }
    bool Working() { return working; }
    bool NoVersion() { return noVersion; }
    unsigned int GetID() { return id; }

    void SetWorking(bool v) { working = v;}

protected:
    friend class Config;

    unsigned int id;
    csString name;
    csString baseURL;
    csString repositoryFile;
    csString versionFile;
    csString filesDirectory;
    csString passphrase;
    bool working;
    bool noVersion;
};

struct SortEntry
{
    SortEntry() { file = false; }
    bool file;
    csString path;
    csString ext;
    csString to;
    csString destFile;
};

struct Proxy
{
    /// bool: proxy enabled?
    bool active;
    /// string: hostname of the proxy
    csString host;
    /// unsigned int: port
    unsigned int port;
};

// This structure holds the general config settings of the updater
class Config
{
public:
    bool Initialize();

    const csString GetSortedPath(const char* path, const char* currentModule);

    bool IsConfig(const char* file);

    // Mirror functions
    Mirror* GetMirror(unsigned int id);
    Mirror* GetMirror();

    void ResetFailures();

    void SetNextMirror();
    bool SetNextWorkingMirror();
    void SetMirror(unsigned int id);

    csString GetCurrentRepositoryURL();
    csString GetCurrentVersionURL();
    csString GetCurrentFilesDirectory();

    bool ShouldIgnoreFile(const char* file);
    bool ShouldIgnoreDir(const char* dir);

    bool CheckCriticalFiles();

    /// should we make backup of files?    
    bool MakeBackup() const;
    void SetBackupMode(bool value);

    void ModuleSetup (csArray<csString>& modules) const;
    
    /// Returns a string indicating the module for the OS of this build
    static const char* GetOSModule();
    /// Returns a string indicating the name of the OS of this build
    static const char* GetOSName();

    Proxy* GetProxy() { return &proxy; }
    
    void SetProxy(bool active, const char* host, int port);

    const csString& GetTempFile() { return tempfile; }

    Config (iDocumentNode* node);
    ~Config ();

    bool DownloadWholeZips() { return wholeZips;}

    int ZipSyncNumber() { return zipSync;}

    // Stores the system files
    csArray<csString> systemFiles;
    csArray<csString> linuxSystemFiles;

    int GetWholeZipPrecent() { return zipPre; }

    const char* GetUpdaterWinPath() { return updaterWin; }
    const char* GetUpdaterMacPath() { return updaterMac; }
    const char* GetUpdaterLinuxPath() { return updaterLinux; }

    bool UpdateUpdaterByMD5() { return updaterMD5; }

    bool HasCustomSortDest(const char* path);
    
    void AddDirOmit(const char* dir) { dirOmits.Push(dir); }
    
    void SetIncludeOS(bool value);
    bool GetIncludeOS() const;

    void SetSkipVerCheck(bool v) { skipVerCheckThisSession = v; }
    bool GetSkipVerCheck() { return skipVerCheckThisSession; }

    bool IsUsingModule(const char* name);  ///< Returns true if the module is in the list
    void SetModuleUse(const char* name, bool use);  ///< Sets the use of the module

private:
    
    void AddModule(const char* name);     ///< Adds a module to the list
    void RemoveModule(const char* name);  ///< Removes a module from the list

    /// master config node of the xml tree
    csRef<iDocumentNode> config;
    /// string: temp files
    csString tempfile;
    /// exts for config files
    csArray<csString> configExt;

    // Stores the omits
    csArray<csString> fileOmits;
    csArray<csString> dirOmits;

    // Stores the configs
    csArray<csString> configFiles;

    // Stores the sorting
    csPDelArray<SortEntry> sortings;

    // Stores the critical files
    csArray<csString> criticalFiles;

    // Proxy settings
    Proxy proxy;

    // Bool for whole zips
    bool wholeZips;

    // Num of files until call sync in zips
    int zipSync;

    // % until whole zip
    int zipPre;

    // Stores the mirrors
    unsigned int activeMirror;
    size_t arrayMirror; // This is the REAL id of the mirror;
    csPDelArray<Mirror> mirrors;

    bool updaterMD5;
    
    csString updaterWin;
    csString updaterMac;       
    csString updaterLinux; ///< The path to the linux updater. 

    bool skipVerCheckThisSession;
};

} // end of namespace updater

#endif

