/******************************************************************************
 * mod_uploader / UploadItemList.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: UploadItemList.h 684 2005-09-15 07:12:00Z svn $
 *****************************************************************************/

#ifndef UPLOADITEMLIST_H
#define UPLOADITEMLIST_H

#include "UploadItem.h"
#include "UploadItemReader.h"
#include "TemplateExecutor.h"
#ifdef MAKE_THUMBNAIL
#include "ThumbnailWriter.h"
#endif

#include "apr_pools.h"

#include <cstdlib>
#include <list>
#include <string>

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

using namespace std;

/**
 * @brief アップロードアイテムの管理を行うクラス．
 */
class UploadItemList
{
public:
    typedef struct ItemInfo {
        UploadItem::header *header;
        const char *file_path;
    } item_info;

    UploadItemList(apr_pool_t *pool,
                   const char *file_dir, const char *thumb_dir,
                   apr_size_t total_number_limit, apr_uint64_t total_size_limit);
    void add(const char *file_path, bool is_new=false);
    void add(item_info *info);
    apr_size_t size() const;
    bool empty() const;
    apr_uint64_t get_total_file_size() const;
    apr_size_t get_thumb_size() const;
    apr_time_t get_mtime() const;
    void update_mtime();
    bool is_need_update(apr_pool_t *pool) const;
    void remove(const char *file_path, const char *password);
    TemplateExecutor::variable *to_varray(apr_pool_t *pool,
                                          apr_size_t start,
                                          apr_size_t size) const;
    TemplateExecutor::variable *to_thumb_varray(apr_pool_t *pool,
                                                apr_size_t start,
                                                apr_size_t size) const;
    item_info **to_array(apr_pool_t *pool, apr_size_t start, apr_size_t size) const;

    static UploadItemList *load(apr_pool_t *pool,
                                const char *file_dir, const char *thumb_dir,
                                apr_size_t total_number_limit,
                                apr_uint64_t total_size_limit);
#ifdef DEBUG
    static void dump_list(UploadItemList *item_list);
#endif
private:
    static const char PATH_CACHE_FILENAME[];
    static const char HEADER_CACHE_FILENAME[];
    static const char TMP_SUFFIX[];
    static const char PATH_CACHE_DELIMITER;

    struct ItemCompare
    {
        bool operator()(const item_info *lhs, const item_info *rhs) const
        {
            return lhs->header->time > rhs->header->time;
        }
    };

    struct ThumbnailCompare
    {
        bool operator()(const string& lhs, const string& rhs) const
        {
            return lhs > rhs;
        }
    };

    typedef list<item_info *> item_list;
    typedef item_list::const_iterator item_iterator;
    typedef list<string> thumb_list;
    typedef thumb_list::const_iterator thumb_iterator;

    UploadItemList(const UploadItemList&);
    UploadItemList &operator=(const UploadItemList&);

    void init();
    bool load_file();
    bool load_file_by_any();
    void load_file_by_item();
    void load_file_by_cache();
    void load_thumb();
    void add_new(item_info *info);
    item_iterator begin() const;
    item_iterator end() const;
    void remove(item_info *info);
    void sort();

    const char *create_tmp_path(apr_pool_t *tmp_pool, const char *name,
                                bool is_buffered, apr_file_t **tmp_file);

    const char *get_tmp_path_cache_path(apr_pool_t *tmp_pool, apr_file_t **cache_file);
    const char *get_tmp_header_cache_path(apr_pool_t *tmp_pool, apr_file_t **cache_file);

    void read_cache(apr_pool_t *tmp_pool,
                    char **paths, UploadItem::header **headers, apr_size_t *number);
    void read_path_cache(apr_pool_t *tmp_pool, char **paths, apr_size_t *number);
    void read_header_cache(apr_pool_t *tmp_pool, UploadItem::header **headers, apr_size_t *number);
    void write_cache();
    void write_path_cache(apr_pool_t *tmp_pool);
    void write_header_cache(apr_pool_t *tmp_pool);

    apr_pool_t *pool_;
    apr_pool_t *data_pool_;
    const char *file_dir_;
    const char *thumb_dir_;
    const char *path_cache_path_;
    const char *header_cache_path_;
    const apr_size_t total_number_limit_;
    const apr_uint64_t total_size_limit_;

    static const char *create_path(apr_pool_t *tmp_pool, const char *dir_path, const char *file_name);

    UploadItemReader reader_;
#ifdef MAKE_THUMBNAIL
    ThumbnailWriter twriter_;
#endif
    apr_uint64_t total_size_;
    item_list ilist_;
    thumb_list tlist_;
    apr_time_t mtime_;
};

#endif

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