/*
    simfinder.cpp    January 13, 2005.

    Copyright (C) 2003-2005 CFbE Research Group,
    Software Engineering Laboratory,
    Graduate School of Information Science,
    Nara Institute of Science and Technology,
    All rights reserved.

    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, (at your option) or
    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 GNU Emacs; see the file COPYING.  If not, write to the
    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/
//---------------------------------------------------------------------------
#pragma hdrstop
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <SysUtils.hpp>
#include <stdio.h>

#include "EDocfbeError.h"
#include "TCFbEToolkit.h"
#include "TCFbESimfinderCommandLineParser.h"
#include "TCFbESimfinderDataLoader.h"

#include "TCFbEDataSetEx.h"
#include "TCFbESimilarityComputationAlgorithm.h"
#include "TCFbEPredictionAlgorithm.h"

#include "TCFbESimfinderOutputCache.h"
//---------------------------------------------------------------------------
#pragma argsused
//---------------------------------------------------------------------------
//
int main(int argc, char* argv[])
{
    // コピーライト表示
    fprintf(stderr, "\n======================================================================\n");
    fprintf(stderr, "%s", TCFbEToolkit::GetToolkit()->GetCopyrightStr("CF based Similarity Analysis"));
    fprintf(stderr, "======================================================================\n");

    try {
        //------------------------------------------------------------
        // コマンドラインを解釈する
        TCFbESimfinderCommandLineParser* Parser;
        try {
            Parser = new TCFbESimfinderCommandLineParser(argc, argv);
        } catch (Exception& e) {
            throw EDocfbeError(-13, "Commandline Parsing", e.Message);
        }

        if (Parser->ErrorCode != 0) {    // エラーあり
            throw EDocfbeError(Parser->ErrorCode, Parser->ErrorParameter, "");
        }

        if (Parser->HelpEnabled) {    // ヘルプ表示
            fprintf(stderr, "%s", Parser->GetHelpString().c_str());

            // 終了処理
            TCFbEToolkit::DeleteToolkit();

            fprintf(stderr, "======================================================================\n");
            return 0;
        }

        fprintf(stderr, "CF based Similarity Analysis is started.\n\n");

        //------------------------------------------------------------
        // データを準備する
        TCFbESimfinderDataLoader* DataLoader;
        try {
            DataLoader = new TCFbESimfinderDataLoader(Parser, true, 3, 1);
        } catch (Exception &e) {
            delete Parser;
            throw EDocfbeError(-13, "Data Loading", e.Message);
        }

        if (DataLoader->ErrorCode != 0) {    // エラーあり
            throw EDocfbeError(DataLoader->ErrorCode, DataLoader->ErrorParameter, "");
        }

        //------------------------------------------------------------
        // 協調フィルタリングを行い，対象メトリクスを予測する
        TCFbESimfinderOutputCache* OutputCache;
        try {
            OutputCache = new TCFbESimfinderOutputCache(Parser, DataLoader, true);
        } catch (Exception &e) {
            delete Parser;
            delete DataLoader;
            throw EDocfbeError(-13, "Similarity analysis", e.Message);
        }           

        //------------------------------------------------------------
        // 結果をファイル，若しくは，標準出力に書き出す
        fprintf(stderr, "(3/3) Outputting results to ");

        if (Parser->OutputFileName.IsEmpty()) {    // 標準出力に出力
            fprintf(stderr, "STDOUT\n");
            fprintf(stdout, "%s\n", OutputCache->GetOutputStringList()->Text.c_str());
        } else {    // ファイルに保存
            fprintf(stderr, "\"%s\"\n", Parser->OutputFileName);
            try {
                OutputCache->GetOutputStringList()->SaveToFile(Parser->OutputFileName);
            } catch (EFCreateError &efce) {
                throw EDocfbeError(-12, Parser->OutputFileName, efce.Message);
            }
        }

        delete OutputCache;
        delete Parser;
        delete DataLoader;

        fprintf(stderr, "    ..... completed: 100.00\%\n\n");
        fprintf(stderr, "CF based Similarity Analysis is successfully completed.\n");

    } catch (EDocfbeError &ede) {    // 異常終了例外を受け取る catch
        fprintf(stderr, "\n\nCF based Similarity Analysis terminated unsuccessfully with the following error.");
        fprintf(stderr, "\n\nError Code %d %s\n\n", ede.ErrorCode, ede.Message);
        fprintf(stderr, "======================================================================\n");
        return ede.ErrorCode;
        
    } catch (...) {
        throw;
    }

    // 終了処理
    TCFbEToolkit::DeleteToolkit();

    fprintf(stderr, "======================================================================\n");
    
    return 0;
}

//---------------------------------------------------------------------------
