//
// $Id: DataCollector.cpp,v 1.1 2004/06/01 17:05:20 bakerj Exp $
//
//************************** Property of the MITRE Corporation ***************************//
//
// Copyright (c) 2003 - The MITRE Corporation
//
// This file is part of the OVAL Query Interpreter project.
//
// The OVAL Query Interpreter 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.
//
// The OVAL Query Interpreter 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 the
// OVAL Query Interpreter; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//****************************************************************************************//


#include "DataCollector.h"

//****************************************************************************************//
//								Probe Class												  //	
//****************************************************************************************//
DataCollector::DataCollector(DBInterface *dbIn)
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Set the db pointer to be used by all probes.
  //
  // -----------------------------------------------------------------------
  db = dbIn;
}

DataCollector::~DataCollector()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Do nothing for now.
  //
  // -----------------------------------------------------------------------
	
}

// ***************************************************************************************	//
//								Public members												//
// ***************************************************************************************	//
void DataCollector::Run()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Simply call CreateProbeVectors() and RunProbes() method
  //
  // -----------------------------------------------------------------------

  string logMessage = " ** creating probe vectors\n";
  cout << logMessage;
  Log::WriteLog(logMessage);

  CreateProbeVectors();

  logMessage = " ** populating OVAL schema\n";
  Log::WriteLog(logMessage);
  cout << logMessage;

  RunProbes();
}

// ***************************************************************************************	//
//								Private members												//
// ***************************************************************************************	//

void DataCollector::CreateProbeVectors()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Execute the needed sql statements to populate the probe vectors
  //
  // -----------------------------------------------------------------------

  string sqlSTMT;

  sqlSTMT = "";
  sqlSTMT.append("SELECT DISTINCT FilePath FROM ");
  sqlSTMT.append("RedHat_FileAttributes_Conf");

  db->ExecSQL(sqlSTMT, &vFileAtts);

  sqlSTMT = "";
  sqlSTMT.append("SELECT DISTINCT FilePath FROM ");
  sqlSTMT.append("RedHat_FileAttributes_Conf");

  db->ExecSQL(sqlSTMT, &vFilePermissions);

  sqlSTMT = "";
  sqlSTMT.append("SELECT DISTINCT ProgramName FROM ");
  sqlSTMT.append("RedHat_InetListeningServers_Conf");

  db->ExecSQL(sqlSTMT, &vInetLS);

  sqlSTMT = "";
  sqlSTMT.append("SELECT DISTINCT Command FROM ");
  sqlSTMT.append("RedHat_PSInfo_Conf");

  db->ExecSQL(sqlSTMT, &vPSInfo);

  sqlSTMT = "";
  sqlSTMT.append("SELECT DISTINCT RPMName FROM ");
  sqlSTMT.append("RedHat_RPMInfo_Conf");

  db->ExecSQL(sqlSTMT, &vRMPInfo);
	
  sqlSTMT = "";
  sqlSTMT.append("SELECT DISTINCT RPMName, RPMTestedEpoch, RPMTestedVersion, RPMTestedRelease FROM ");
  sqlSTMT.append("RedHat_RPMVersionCompare_Conf ORDER BY RPMName ASC");

  db->ExecSQL(sqlSTMT, &vdbRPMVC);
}

void DataCollector::RunProbes()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Run all probes using the probe vectors to provide data input for 
  //	the probe
  //
  // -----------------------------------------------------------------------

  Probe *myProbe		= NULL;
  ProbeData *myProbeData	= NULL;
  ProbeData *tmpProbeData	= NULL;
  pdVector vMyResults;
  stringVector::iterator myIterator;
	
  /////////////////////////////////////////////
  //	File Attributes probe
  /////////////////////////////////////////////
  myProbe = new FileProbe();
  for (myIterator=this->vFileAtts.begin(); myIterator!=this->vFileAtts.end(); myIterator++) {
    myProbeData = new FileAttributeData((*myIterator));

    vMyResults = myProbe->Run(myProbeData);

    tmpProbeData = NULL;
    while(vMyResults.size() !=0) {
      tmpProbeData = vMyResults[vMyResults.size()-1];
      tmpProbeData->Write(db);
      vMyResults.pop_back();
      delete tmpProbeData;
      tmpProbeData = NULL;
    }

    delete myProbeData;
    myProbeData = NULL;
  }
  delete myProbe;
  myProbe = NULL;
	
  /////////////////////////////////////////////
  //	File Permissions probe
  /////////////////////////////////////////////
  myProbe = new FileProbe();
  for (myIterator=this->vFilePermissions.begin(); myIterator!=this->vFilePermissions.end(); myIterator++) {
    myProbeData = new FilePermissionData((*myIterator));

    vMyResults = myProbe->Run(myProbeData);

    tmpProbeData = NULL;
    while(vMyResults.size() !=0) {
      tmpProbeData = vMyResults[vMyResults.size()-1];
      tmpProbeData->Write(db);
      vMyResults.pop_back();
      delete tmpProbeData;
      tmpProbeData = NULL;
    }

    delete myProbeData;
    myProbeData = NULL;
  }
  delete myProbe;
  myProbe = NULL;
	
  /////////////////////////////////////////////
  //	Inet Listening Servers probe
  /////////////////////////////////////////////
  myProbe = new InetListeningServersProbe();

  for (myIterator=this->vInetLS.begin(); myIterator!=this->vInetLS.end(); myIterator++) {
    myProbeData = new InetListeningServersData((*myIterator));

    vMyResults = myProbe->Run(myProbeData);

    tmpProbeData = NULL;
    while(vMyResults.size() !=0) {
      tmpProbeData = vMyResults[vMyResults.size()-1];
      tmpProbeData->Write(db);
      vMyResults.pop_back();
      delete tmpProbeData;
      tmpProbeData = NULL;
    }

    delete myProbeData;
    myProbeData = NULL;
  }
  delete myProbe;
  myProbe = NULL;
	
  /////////////////////////////////////////////
  //	Process probe
  /////////////////////////////////////////////
  myProbe = new ProcessProbe();

  for (myIterator=this->vPSInfo.begin(); myIterator!=this->vPSInfo.end(); myIterator++) {
    myProbeData = new ProcessData((*myIterator));

    vMyResults = myProbe->Run(myProbeData);

    tmpProbeData = NULL;
    while(vMyResults.size() !=0) {
      tmpProbeData = vMyResults[vMyResults.size()-1];
      tmpProbeData->Write(db);
      vMyResults.pop_back();
      delete tmpProbeData;
      tmpProbeData = NULL;
    }

    delete myProbeData;
    myProbeData = NULL;
  }
  delete myProbe;
  myProbe = NULL;
	
  /////////////////////////////////////////////
  //	RPMInfo probe
  /////////////////////////////////////////////
  myProbe = new RPMInfoProbe();

  for (myIterator=this->vRMPInfo.begin(); myIterator!=this->vRMPInfo.end(); myIterator++) {
    myProbeData = new RPMInfoData((*myIterator));

    vMyResults = myProbe->Run(myProbeData);

    tmpProbeData = NULL;
    while(vMyResults.size() !=0) {
      tmpProbeData = vMyResults[vMyResults.size()-1];
      tmpProbeData->Write(db);
      vMyResults.pop_back();
      delete tmpProbeData;
      tmpProbeData = NULL;
    }

    delete myProbeData;
    myProbeData = NULL;
  }
  delete myProbe;
  myProbe = NULL;
		
  /////////////////////////////////////////////
  //	RPM Version Compare probe
  /////////////////////////////////////////////
   myProbe = new RPMVersionCompareProbe();
  vDBRecord::iterator myDBVIterator;

  for (myDBVIterator=this->vdbRPMVC.begin(); myDBVIterator!=this->vdbRPMVC.end(); myDBVIterator++) {
    // Get the values for name, tested epoch, tested version, and tested release.	  
    stringVector svTmp = (*myDBVIterator);
    string name = svTmp.at(0);
    string testedEpoch = svTmp.at(1);
    string testedVersion = svTmp.at(2);
    string testedRelease = svTmp.at(3);
 
    myProbeData = new RPMVersionCompareData(name, testedVersion, testedRelease, testedEpoch);

    vMyResults = myProbe->Run(myProbeData);

    tmpProbeData = NULL;
    while(vMyResults.size() !=0) {
      tmpProbeData = vMyResults[vMyResults.size()-1];
      tmpProbeData->Write(db);
      vMyResults.pop_back();
      delete tmpProbeData;
      tmpProbeData = NULL;
    }

    delete myProbeData;
    myProbeData = NULL;
  }
  delete myProbe;
  myProbe = NULL;

  /////////////////////////////////////////////
  //	Uname probe
  /////////////////////////////////////////////
  myProbe = new UnameProbe();
  myProbeData = new UnameData();
  vMyResults = myProbe->Run(myProbeData);
	
  if(vMyResults.size() !=0) {
    myProbeData = vMyResults[vMyResults.size()-1];
    myProbeData->Write(db);
    vMyResults.pop_back();
  }
  delete myProbeData;
  myProbeData = NULL;
	
  delete myProbe;
  myProbe = NULL;
}


