/*
 * $Id: scdb.h,v 1.4 2004/09/06 14:21:22 jg Exp $
 *
 *
 * Project     :  SCPM (System Configuration Profile Management)
 * Module      :  SCPM database
 * File        :  scdb.hh
 * Description :  defines SCDB access and management functions
 * Author      :  Joachim Gleissner <jg@suse.de>
 *
 * Copyright 2002-2004 SuSE Linux AG
 *
 * Released under the terms of the GNU General Public License
 * (see file COPYRIGHT in project root directory).
 *
 */
#ifndef SCDB_H
#define SCDB_H

using namespace std;

#include <vector>
#include <string>
#include <iostream>
#include <sys/stat.h>

class SCDB
{
public:
  friend class SCPM;
  friend class SCDBUtil;


  typedef struct dbinfo_t {
    string version;
    string type;
    bool is_local;
  };

  typedef struct resource_dep_t {
    string name;
    string type;
  };

  typedef struct db_action_failed
  {
  public:
    db_action_failed( string r ) { reason = r; };
    string reason;
  };

  static const int db_state_ok                  = 0;
  static const int db_state_open_failed         = 1;
  static const int db_state_corrupt             = 2;
  static const int db_state_version_unsupported = 3;

  static SCDB * GetHandle( ) { return scdb_handle; };

  // scdb specific functions
  struct dbinfo_t GetDBInfo( );
  int LoadDB( )  throw( db_action_failed );
  int LoadDB( string dbfile )  throw( db_action_failed );
  int LoadDB( istream &input, bool quick=false )  throw( db_action_failed );
  void SaveDB( )  throw( db_action_failed );
  void SaveDB( ostream &output )  throw( db_action_failed );
  void DropDB( );
  bool Modified( ) { return modified; };
  string GetSCDBVersion( );
  void   SetSCDBVersion( string version );
  string GetFormat( ) { return "xml"; };
  string GetFormatVersion( );
  bool UpToDate();

  // scdb global functions
  void SetStatusFlag( string status_flag, bool value ) throw( db_action_failed );
  bool GetStatusFlag( string status_flag ) throw( db_action_failed );
  void SetStatusKey( string status_key, string value ) throw( db_action_failed );
  string GetStatusKey( string status_key ) throw( db_action_failed );
  void SetActiveProfile( string profile_name ) throw( db_action_failed );
  string GetActiveProfile( ) throw( db_action_failed );
  vector<string> GetProfiles( ) throw( db_action_failed );

  // resource functions
  bool ResourceExists( string resource_name, string resource_type )
    throw( db_action_failed );
  void ResourceAdd( string resource_name, string resource_type )
    throw( db_action_failed );
  void ResourceAddType( string resource_type )
    throw( db_action_failed );
  void ResourceDelete( string resource_name, string resource_type )
    throw( db_action_failed );
  void ResourceAddDep( string resource_name, string resource_type, string dep_name, string dep_type )
    throw( db_action_failed );
  void ResourceCleanDeps( string resource_name, string resource_type )
    throw( db_action_failed );
  vector<resource_dep_t> ResourceGetDeps( string resource_name, string resource_type )
    throw( db_action_failed );
  vector<string> ResourceGetTypes( )
    throw( db_action_failed );
  vector<string> ResourceGetNames( string resource_type )
    throw( db_action_failed );
  void ResourceAddData( string resource_name, string resource_type,
			string data_entry, string data_value )
    throw( db_action_failed );
  void ResourceClearData( string resource_name, string resource_type )
    throw( db_action_failed );
  void ResourceGetData( string resource_name, string resource_type,
			vector<string> &data_entries, vector<string> &data_values )
    throw( db_action_failed );

  // profile functions
  bool ProfileExists( string profile_name )
    throw( db_action_failed );
  void ProfileAdd( string profile_name )
    throw( db_action_failed );
  void ProfileDelete( string profile_name )
    throw( db_action_failed );
  void ProfileAddResource( string profile_name, string resource_name, string resource_type )
    throw( db_action_failed );
  void ProfileDeleteResource( string profile_name, string resource_name, string resource_type )
    throw( db_action_failed );
  void ProfileClearResources( string profile_name, string resource_type="all" )
    throw( db_action_failed );
  bool ProfileHasResource( string profile_name, string resource_name, string resource_type )
    throw( db_action_failed );
  bool ProfileGetFlag( string profile, string flag )
    throw( db_action_failed );
  void ProfileSetFlag( string profile, string flag, bool value )
    throw( db_action_failed );
  string ProfileGetKey( string profile, string key )
    throw( db_action_failed );
  void ProfileSetKey( string profile, string key, string value )
    throw( db_action_failed );
  string ProfileGetScript( string profile, string script_name )
    throw( db_action_failed );
  void ProfileSetScript( string profile, string script_name, string script_location )
    throw( db_action_failed );
  vector<string> ProfileGetResourceTypes( string profile )
    throw( db_action_failed );
  vector<string> ProfileGetResources( string profile, string resource_type )
    throw( db_action_failed );

  // generic access functions
  void Dump( ostream &output, string key="root" )
    throw( db_action_failed );
  void SetValue( string key, string value )
    throw( db_action_failed );
  string GetValue( string key )
    throw( db_action_failed );
  void AddNodes( string key, string value="" ) throw( db_action_failed );
  void DeleteNodes( string key ) throw( db_action_failed );
  void RenameNodes( string key, string name ) throw( db_action_failed );

  // SCDB file interface helpers
  struct no_such_file{};
  struct file_exists{};

  bool FileExists( const string &profile, const string &resource_type,
		   const string &resource_name )
    throw( db_action_failed );
  void FileSave( const string &profile, const string &resource_type, 
		 const string &resource_name, istream &in, struct stat *st=NULL)
    throw( db_action_failed );
  void FileRestore( const string &profile, const string &resource_type, 
		    const string &resource_name, ostream &out,
		    struct stat *st=NULL )
    throw( db_action_failed, no_such_file );
  void FileCopy( const string &profile, const string &dest_profile, const string &resource_type,
		 const string &resource_name ) 
    throw( db_action_failed, no_such_file, file_exists );
  void FileDelete( const string &profile, const string &resource_type, 
		   const string &resource_name )
    throw( db_action_failed, no_such_file );
  string &FileGetMD5( const string &profile, const string &resource_type, 
		      const string &resource_name )
    throw( db_action_failed, no_such_file );
  bool FileHasBackup( const string &profile, const string &resource_type,
		      const string &resource_name );

private:
  static SCDB * scdb_handle;
  bool modified;

};

#endif
