/*
 * vdr-podcatcher - A plugin for the Linux Video Disk Recorder
 * Copyright (c) 2006 Tobias Grimm <vdr@e-tobi.net>
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: localfilecache_test.cc 3219 2006-04-16 15:06:35Z svntobi $
 *
 */

#include <time.h>
#include <sstream>
#include <cxxtest/TestSuite.h>
#include "localfilecache.h"
#include "sdbmhashcalculator.h"

using namespace std;

#define TEST_CACHE_DIR "test.cache"

class LocalFileCacheTest: public CxxTest::TestSuite
{
    private:
        LocalFileCache* localFileCache;

    private:
        void CreateCachedFile(string fileName, int age)
        {
            string cachedFileName = SdbmHashCalculator::Calculate(fileName);

            time_t fileTime = time(NULL) - age * 60 * 60;
            struct tm *timeComponents = localtime(&fileTime);

            char formattedTime[11];
            strftime(formattedTime, 11, "%y%m%d%H%M", timeComponents);

            string touchCommand = string("touch -t ")  + formattedTime + " " +
              TEST_CACHE_DIR + "/" + cachedFileName;

            system(touchCommand.c_str());
        }

    public:
        void setUp()
        {
            system("rm -rf " TEST_CACHE_DIR);
            system("mkdir " TEST_CACHE_DIR);
            localFileCache = new LocalFileCache(TEST_CACHE_DIR);
        }

        void tearDown()
        {
            delete localFileCache;
            system("rm -rf " TEST_CACHE_DIR);
        }

        void TestEmptyCache()
        {
            TS_ASSERT(NULL == localFileCache->CreateStreamByUrl("foo://bar").get());
        }

        void TestPut()
        {
            stringstream input("foo");
            localFileCache->Put(input, "http://foo");

            ref_ptr<istream> output = localFileCache->CreateStreamByUrl("http://foo");
            TS_ASSERT(NULL != output.get());

            stringstream outputStr;
            outputStr << output->rdbuf();
            TS_ASSERT_EQUALS(input.str(), outputStr.str());
        }

        void TestDifferentUrls()
        {
            stringstream input1("foo");
            stringstream input2("bar");

            localFileCache->Put(input1, "http://foo/baz");
            localFileCache->Put(input2, "http://bar/baz");

            stringstream output1;
            stringstream output2;

            output1 << localFileCache->CreateStreamByUrl("http://foo/baz")->rdbuf();
            output2 << localFileCache->CreateStreamByUrl("http://bar/baz")->rdbuf();

            TS_ASSERT_EQUALS(input1.str(), output1.str());
            TS_ASSERT_EQUALS(input2.str(), output2.str());
        }

        void TestGetAge()
        {
            CreateCachedFile("testFile", 5);
            TS_ASSERT_EQUALS(5, localFileCache->GetAge("testFile"));

            CreateCachedFile("testFile", 0);
            TS_ASSERT_EQUALS(0, localFileCache->GetAge("testFile"));
        }

        void TestIsCached()
        {
            TS_ASSERT(!localFileCache->IsCached("testFile"));

            CreateCachedFile("testFile", 0);
            TS_ASSERT(localFileCache->IsCached("testFile"));
        }

        void TestNothingToCleanUp()
        {
            CreateCachedFile("testFile1", 0);
            CreateCachedFile("testFile2", 5);
            TS_ASSERT(localFileCache->IsCached("testFile1"));
            TS_ASSERT(localFileCache->IsCached("testFile2"));

            localFileCache->CleanUp(10);

            TS_ASSERT(localFileCache->IsCached("testFile1"));
            TS_ASSERT(localFileCache->IsCached("testFile2"));
        }

        void TestCleanUpOldFilesOnly()
        {
            CreateCachedFile("testFile1", 5);
            CreateCachedFile("testFile2", 10);
            TS_ASSERT(localFileCache->IsCached("testFile1"));
            TS_ASSERT(localFileCache->IsCached("testFile2"));

            localFileCache->CleanUp(10);

            TS_ASSERT(localFileCache->IsCached("testFile1"));
            TS_ASSERT(!localFileCache->IsCached("testFile2"));
        }
};
