// -*- mode: C++; c-file-style: "stroustrup"; c-basic-offset: 4; -*-
////////////////////////////////////////////////////////////////////
//
// $Id: parser.cpp 816 2011-09-10 13:19:07Z Sebastian Kupferschmid $
//
////////////////////////////////////////////////////////////////////

#include "expression_builder.h"
#include "parser.h"
#include "system.h"
#include "system_builder.h"
#include "target.h"
#include "task.h"

#include "common/message.h"

#include <cstring>
#include <fstream>
#include <utap/utap.h>
#include <vector>

using namespace std;

static bool check_file(const char* filename) {
    if (strcmp(filename, "") == 0) {
	return false;
    }
    FILE* file = fopen(filename, "r");
    if (!file) {
	error() << "file '" << filename << "' does not exist" << endl;
	return false;
    }
    fclose(file);
    return true;
}

Task* SystemParser::operator()(const std::string& tafile, bool oldSyntax) {
    return operator()(tafile.c_str(), oldSyntax);
}

Task* SystemParser::operator()(const char* tafile, bool oldSyntax) {
    return operator()(tafile, "", oldSyntax);
}

Task* SystemParser::operator()(const string& tafile, const string& qfile, bool oldSyntax) {
    return operator()(tafile.c_str(), qfile.c_str(), oldSyntax);
}

Task* SystemParser::operator()(const char* tafile, const char* qfile, bool oldSyntax) {
    check_file(tafile);
    bool has_qfile = check_file(qfile);

    UTAP::TimedAutomataSystem tasystem;
    if (strlen(tafile) > 4 && strcasecmp(".xml", tafile + strlen(tafile) - 4) == 0) {
        parseXMLFile(tafile, &tasystem, !oldSyntax);
    } else {
        FILE *file = fopen(tafile, "r");       
        parseXTA(file, &tasystem, !oldSyntax);           
        fclose(file);
    }
    vector<UTAP::error_t>::const_iterator it;
    const vector<UTAP::error_t> &errors = tasystem.getErrors();
    const vector<UTAP::error_t> &warns = tasystem.getWarnings();
    
    for (it = errors.begin(); it != errors.end(); it++) {
        cerr << "error: " << *it << endl;
    }
    for (it = warns.begin(); it != warns.end(); it++) {
        cerr << "waring: " << *it << endl;
    }
    if (!errors.empty()) {            
        return NULL;
    }
    
    SystemBuilder builder;
    System* system = builder.buildSystem(&tasystem);
    if (has_qfile) {
	ExpressionBuilder ebuilder(system->resolver);
	Target* target = ebuilder.buildTarget(qfile, &tasystem, system);
	return new Task(system, target);
    } else {
	return new Task(system, new Target);
    }
}
