/*!
  @header FTModifyGraphTEST
  @abstract Module of FT
 
  @availability OS X, GNUstep
  @copyright 2004, 2005 Free Software Foundation, Inc.
  
  Author: Oliver Langer

  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 of the License, or
  (at your option) 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 this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  <pre>
  -------------------------------------------------------------------------
  Modification history

  03.08.05 ola     initial version
  -------------------------------------------------------------------------
  </pre>
*/

#include <FTModifyGraphTEST.h>

@implementation FTModifyGraphTEST
- testGraphModification {
  id <FTGraphManager> graphManager;
  id <FTGraph> graph;
  id <FTId> graphId;
  id <FTId> nid1,nid2,nid3,ne1, ne2;
  id <FTObjectToIdMapper> objectToIdMapper;
  id <FTObjectToIdMapper> graphIdMapper;
  id <FTNode> n1,n2,n3;
  id <FTEdge> edge;
  id <FTTransaction> transaction;
  id <ECIterator> nodeIterator;
  BOOL gotException;
  
  NSLog( @"FTModifyGraphTEST::testGraphModification: BEGINNING...." );
  
  EC_AUTORELEASEPOOL_BEGIN
  objectToIdMapper = [session defaultObjectToIdMapper];
  graphManager = [session graphManager];

  NSLog( @"Now creating graph..." );
  transaction = [session beginTransactionWithParent: nil
    withSettings: nil];
  
  graphId = [objectToIdMapper mapObject: @"modifyTestGraph"];
  graph = [graphManager createGraphWithId: graphId];
  ECAssertTrue( nil != graph, @"Graph creation failed!" );
  
  NSLog( @"FTModifyGraphTEST::Now creating some nodes..." );
  graphIdMapper = [[graph objectToIdMapper] retain];
  ECAssertTrue( nil != graphIdMapper,
     @"getting objectToIdMapper of graph FAILED" );
  
  NSLog( @"FTModifyGraphTEST::Creating nodes and relationships..." );
  nid1 = [graphIdMapper mapObject: @"fatherNode"];
  nid2 = [graphIdMapper mapObject: @"child_1_Node"];
  nid3 = [graphIdMapper mapObject: @"child_2_Node"];
  ne1 = [graphIdMapper mapObject: @"edge1"];
  ne2 = [graphIdMapper mapObject: @"edge2"];
  
  n1 = [graph createNodeWithId: nid1];
  n2 = [graph createNodeWithId: nid2];
  n3 = [graph createNodeWithId: nid3];
  
  NSLog( @"FTModifyGraphTEST::Created nodes n1, n2, n3" );
  
  edge = [n1 createAndAppendEdgeWithId: ne1 withTargetNode: n2];
  edge = [n1 createAndAppendEdgeWithId: ne2 withTargetNode: n3];
  
  NSLog( @"FTModifyGraphTEST::Performing a commit..." );
  [transaction commit];

  NSLog( @"Now iterating through all nodes..." );
  nodeIterator = [graph nodeIterator];
  while( [nodeIterator hasNext] ) {
    id <FTNode> node = [nodeIterator next];
    
    NSLog( @">>%@", [node nodeId] );
  }
 
  NSLog( @"FTModifyGraphTEST::Graph created! Now trying to read the graph" );
  [graph close];

  graphId = [objectToIdMapper mapObject: @"modifyTestGraph"];
  graph = [graphManager graphWithId: graphId];

  NSLog( @"FTModifyGraphTEST::Got graph! Now removing edge to node "\
    "child_1_Node..." );
  transaction = [session beginTransactionWithParent: nil
    withSettings: nil];
    
  n1 = [graph nodeWithId: nid1];
  [n1 removeAllOutgoingNodesWithId: nid2];
  
  nodeIterator = [n1 outgoingNodes];
  while( [nodeIterator hasNext] ) {
    id <FTNode> node = [nodeIterator next];
    
    NSLog( @">>%@", [node nodeId] );
  }
  
  [transaction commit];
  NSLog( @"FTModifyGraphTEST::Closing Graph..." );
  [graph close];
  
  /**
   * Now we check the resulting graph
   */
  NSLog( @"FTModifyGraphTEST::Checking the resulting graph..." );
  graphId = [objectToIdMapper mapObject: @"modifyTestGraph"];
  graph = [graphManager graphWithId: graphId];

  NSLog( @"FTModifyGraphTEST::Got graph! Now reading edges..." );
  n1 = [graph nodeWithId: nid1];
  
  nodeIterator = [n1 outgoingNodes];
  
  ECAssertTrue( [nodeIterator hasNext], @"Unable to get child node 2!" );
  n3 = [nodeIterator next];
  
  ECAssertTrue( YES == [[n3 nodeId] isEqual: nid3], @"Expected node n2!" );
  ECAssertTrue( NO == [nodeIterator hasNext], @"Father node should have ONE "\
    "successor only!" );

  NSLog( @"FTModifyGraphTEST: Now asking for incoming nodes of node n3..."\
    "(father node)" );
  nodeIterator = [n3 incomingNodes];
  while( [nodeIterator hasNext] ) {
    id <FTNode> node = [nodeIterator next];
    
    NSLog( @">>%@", [node nodeId] );
  }
  
  NSLog( @"FTModifyGraphTEST: Now asking for incoming nodes of node n2..."\
    "(none...)" );
  nodeIterator = [n2 incomingNodes];
  while( [nodeIterator hasNext] ) {
    id <FTNode> node = [nodeIterator next];
    
    NSLog( @">>%@", [node nodeId] );
  }
  
  NSLog( @"Now iterating through all nodes..." );
  nodeIterator = [graph nodeIterator];
  while( [nodeIterator hasNext] ) {
    id <FTNode> node = [nodeIterator next];
    
    NSLog( @">>%@", [node nodeId] );
  }
 
  [graph close];
  
  NSLog( @"Now testing deletion of a node: ");
  graph = [graphManager graphWithId: graphId];
  NSLog( @"Removing node child_1_Node..." );
  transaction = [session beginTransactionWithParent: nil
    withSettings: nil];

  n2 = [graph nodeWithId: nid2];
  [graph removeNode: n2];
  [transaction commit];

  NSLog( @"Now iterating through all nodes..." );
  nodeIterator = [graph nodeIterator];
  while( [nodeIterator hasNext] ) {
    id <FTNode> node = [nodeIterator next];
    
    NSLog( @">>%@", [node nodeId] );
  }
 
  NSLog( @"Trying to remove child_2_Node which should fail since there "\
    "are still incoming links..." );

  transaction = [session beginTransactionWithParent: nil
    withSettings: nil];

  n3 = [graph nodeWithId: nid3];
  gotException = NO;
  NS_DURING
    [graph removeNode: n3];
  NS_HANDLER
    NSLog( @"Got EXPECTED exception: %@", localException );
    gotException = YES;
  NS_ENDHANDLER

  ECAssertTrue( gotException, @"Remove operation for node child_2_Node did "\
    "NOT throw an exception but it should since this node has incoming "\
    "links..." );

  [transaction commit];
  [graph close];

  EC_AUTORELEASEPOOL_END
  
  NSLog( @"FTModifyGraphTEST::testGraphModification: FINISHED" );
  
  return self;
}

@end
