/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Daniela Dorner, 01/2005 <mailto:dorner@astro.uni-wuerzburg.de>
!
!   Copyright: MAGIC Software Development, 2000-2005
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//
// SetStatus.C
// ===========
//
/////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <iomanip>
#include <fstream>

#include <TEnv.h>

#include <MTime.h>

#include <MSQLServer.h>
#include <TSQLRow.h>
#include <TSQLResult.h>

using namespace std;


Bool_t CheckReset(TEnv &rc, TString table, TString column, TString value)
{
    if (value!="NULL")
    {
        cout << "everything ok - no reset needed" << endl;
        return kTRUE;
    }

    TString reset=rc.GetValue(table+"."+column+".Reset", "no");
    if (reset.Contains("no"))
    {
        cout << "you can't reset " << column << "." << endl;
        return kFALSE;
    }

    cout << "reset is possible" << endl;
    return kTRUE;
}

TString CheckDefault(MSQLServer &serv, TEnv &rc, TString primary, TString table, TString influence)
{
    TString query(Form("SELECT %s FROM %s WHERE %s=%s",
                       influence.Data(), table.Data(),
                       rc.GetValue(table+".Primary", ""), primary.Data()));

    TSQLResult *res = serv.Query(query);
    if (!res)
        cout << "Error - no run to check" << endl;

    MTime t, t0;
    //set time t to 'no-version-value',
    //which is in this case equivalent to NULL
    t.Set(1970,1,1,0,0,0); 
    t0.Set(1970,1,1,0,0,0);

    TSQLRow *row=0;
    while ((row = res->Next()))
    {
        if (row && (*row)[0])
            t.SetSqlDateTime((*row)[0]);

        cout << "t : " << t  << endl;
        cout << "t0: " << t0 << endl;

        return t()-t0()>0 ? "no" : "yes";
    }
}

Int_t SetInfluences(MSQLServer &serv, TEnv &rc, TString primary, TString table, TString column, TString value, Bool_t resetall)
{
    cout << "set influenes for " << table << "." << column << endl;

    TString influences  = rc.GetValue(table+"."+column+".Influences", "");

    TString query(Form("UPDATE %s SET %s=%s",
                       table.Data(), column.Data(), value.Data()));

    while (!influences.IsNull() && resetall)
    {
        influences = influences.Strip(TString::kBoth);

        Int_t idx = influences.First(' ');
        if (idx<0)
            idx = influences.Length();

        TString influence = influences(0, idx);
        influences.Remove(0, idx);

        TString deflt  = rc.GetValue(influence+".Default", "");

        if (deflt=="check")
            deflt=CheckDefault(serv, rc, primary, table, influence);

        if (deflt=="yes")
            continue;

        query+=Form(", %s=NULL", influence.Data());
    }

    query+=Form(" WHERE %s='%s'", rc.GetValue(table+".Primary", ""), primary.Data());

//    cout << "query: " << query << endl;

    TSQLResult *res = serv.Query(query);
    if (!res)
        return 0;

    return 1;
}

int setstatus(TString primary, TString table, TString column, TString value, Bool_t resetall=kTRUE)
{
    TEnv env("sql.rc");

    MSQLServer serv(env);
    if (!serv.IsConnected())
    {
        cout << "ERROR - Connection to database failed." << endl;
        return 0;
    }
    cout << "setstatus" << endl;
    cout << "---------" << endl;
    cout << endl;
    cout << "Connected to " << serv.GetName() << endl;
    cout << endl;

    TEnv rc("steps.rc");

    return !CheckReset(rc, table, column, value) ? 0 : SetInfluences(serv, rc, primary, table, column, value, resetall);

}

