/******************************************************************************
 * mod_uploader / UploaderConfig.h
 ******************************************************************************
 * Copyright (C) 2005 Tetsuya Kimata <kimata@acapulco.dyndns.org>
 *
 * All rights reserved.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must
 *    not claim that you wrote the original software. If you use this
 *    software in a product, an acknowledgment in the product
 *    documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must
 *    not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 *    distribution.
 *
 * $Id: UploaderConfig.h 674 2005-09-13 18:31:36Z svn $
 *****************************************************************************/

#ifndef UPLOADERCONFIG_H
#define UPLOADERCONFIG_H

#define APR_NOT_DONE_YET 0

#include "httpd.h"
#include "apr_pools.h"
#include "apr_time.h"
#include "apr_global_mutex.h"
#ifdef LOCK_TYPE_MUTEX
#include "apr_thread_mutex.h"
#else
#include "apr_thread_rwlock.h"
#endif

#undef strtoul

#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION

#include "RFC1867ParserImpl.h"
#include "UploadItemWriter.h"
#include "UploadItemReader.h"
#include "UploadItemList.h"
#include "TemplateLexer.h"
#include "TemplateParser.h"
#include "TemplateExecutor.h"


#include <cstdlib>

#ifdef HAVE_CONFIG_H
#include "mod_uploader_config.h"
#endif

using namespace std;

/**
 * @brief アップローダの設定を保持するクラス．
 */
class UploaderConfig {
public:
    typedef struct PageTemplate {
        TemplateLexer::ident_map *imap;
        TemplateParser::node *node;
        apr_time_t mtime;

        PageTemplate()
        {
            imap    = NULL;
            node    = NULL;
            mtime   = 0;
        }
    } page_template;

    UploaderConfig();
    ~UploaderConfig();

    void init(request_rec *r);
    void finalize();

    page_template *get_view_template(apr_pool_t *pool);
    page_template *get_progress_template(apr_pool_t *pool);
    page_template *get_download_template(apr_pool_t *pool);
    page_template *get_thumb_template(apr_pool_t *pool);
    page_template *get_error_template(apr_pool_t *pool);

    UploadItemReader *get_ureader(apr_pool_t *pool);
    UploadItemWriter *get_uwriter(apr_pool_t *pool);
    void read_lock();
    void read_unlock();
    void gwrite_lock();
    void gwrite_unlock();

    // 面倒くさいので public
    const char *url;
    const char *file_dir;
    const char *thumb_dir;
    const char *tmp_dir;
    const char *magick_dir;
    const char *view_tmpl_path;
    const char *progress_tmpl_path;
    const char *download_tmpl_path;
    const char *thumb_tmpl_path;
    const char *error_tmpl_path;
    apr_uint64_t total_file_size_limit;
    apr_size_t total_file_number_limit;
    apr_size_t max_file_size;
    apr_size_t per_page_item_number;
    apr_size_t remove_item_number;

    UploadItemList *item_list;
    TemplateExecutor *texecutor;
    UploadParser *uparser;

private:
    static const apr_uint64_t TOTAL_FILE_SIZE_LIMIT;
    static const apr_size_t TOTAL_FILE_NUMBER_LIMIT;
    static const apr_size_t MAX_FORM_FILE_SIZE;
    static const apr_size_t MAX_FORM_TEXT_SIZE;
    static const apr_size_t MAX_FORM_ITEM_NUMBER;
    static const apr_size_t PER_PAGE_ITEM_NUMBER;
    static const apr_size_t ITEM_RELOAD_THRESHOLD;

    void exec_init();
    void validate();
#if APR_HAS_THREADS
    void init_lock();
#endif
    void load_list();
    void update_list(apr_pool_t *pool);
    void load_template(apr_pool_t *pool, apr_pool_t **tmpl_pool,
                       const char *template_path, page_template *tmpl);

    void write_lock();
    void write_unlock();
    void global_lock();
    void global_unlock();

    static apr_time_t get_mtime(apr_pool_t *pool, const char *path);

    apr_pool_t *pool_;
    page_template *view_tmpl_;
    apr_pool_t *view_tmpl_pool_;
    page_template *progress_tmpl_;
    apr_pool_t *progress_tmpl_pool_;
    page_template *download_tmpl_;
    apr_pool_t *download_tmpl_pool_;
    page_template *thumb_tmpl_;
    apr_pool_t *thumb_tmpl_pool_;
    page_template *error_tmpl_;
    apr_pool_t *error_tmpl_pool_;
    apr_pool_t *list_pool_;
    apr_global_mutex_t *glock_;
#if APR_HAS_THREADS
#ifdef LOCK_TYPE_MUTEX
    apr_thread_mutex_t *lock_;
#else
    apr_thread_rwlock_t *lock_;
#endif
#endif
    volatile bool is_init_;
};

#endif

// Local Variables:
// mode: c++
// buffer-file-coding-system: euc-japan-dos
// End:
