/**
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.maven.mercury.metadata.sat;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import org.apache.maven.mercury.artifact.ArtifactBasicMetadata;
import org.apache.maven.mercury.artifact.ArtifactMetadata;
import org.apache.maven.mercury.metadata.ClassicDepthComparator;
import org.apache.maven.mercury.metadata.ClassicVersionComparator;
import org.apache.maven.mercury.metadata.MetadataTreeNode;

/**
 * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
 */
public class DefaultSatSolverTest
    extends TestCase
{
  DefaultSatSolver ss;
  String title;
  
  MetadataTreeNode tree;
  
  ArtifactMetadata a1 = new ArtifactMetadata("t:a:1");
  ArtifactMetadata b1 = new ArtifactMetadata("t:b:1");
  ArtifactMetadata b2 = new ArtifactMetadata("t:b:2");
  ArtifactMetadata b3 = new ArtifactMetadata("t:b:3");
  ArtifactMetadata c1 = new ArtifactMetadata("t:c:1");
  ArtifactMetadata c2 = new ArtifactMetadata("t:c:2");

  ArtifactMetadata d1 = new ArtifactMetadata("t:d:1");
  
  //----------------------------------------------------------------------
  protected void setUp()
  throws Exception
  {
    super.setUp();
  }
  //----------------------------------------------------------------------
  public void testDedupe()
  {
    List<MetadataTreeNode> list = new ArrayList<MetadataTreeNode>();
    
    list.add(  new MetadataTreeNode( new ArtifactMetadata("a:a:1"), null, null ) );
    list.add(  new MetadataTreeNode( new ArtifactMetadata("a:a:1"), null, null ) );
    list.add(  new MetadataTreeNode( new ArtifactMetadata("a:a:1"), null, null ) );
    list.add(  new MetadataTreeNode( new ArtifactMetadata("b:b:1"), null, null ) );
    list.add(  new MetadataTreeNode( new ArtifactMetadata("b:b:1"), null, null ) );
    list.add(  new MetadataTreeNode( new ArtifactMetadata("a:a:1"), null, null ) );
    
    DefaultSatSolver.removeDuplicateGAVs( list );
    
    System.out.println(list);
    
    assertEquals( 2, list.size() );
  }
  
  
  private int f( int a, int b )
  {
    return -a + b;
  }
  //----------------------------------------------------------------------
  //       d:d:1 - c:c:[2,4)
  //      / 
  // a:a:1
  //      \     
  //       b:b:2 - c:c:1
  //----------------------------------------------------------------------
  public void testReNumeration()
  throws SatException, IOException
  {
    title = "testReNumeration";
    System.out.println("\n\n==========================\n"+title+"\n");
    
    MetadataTreeNode na1 = new MetadataTreeNode( a1, null, null )
      .addQuery(d1)
      .addQuery(b2)
    ;
    
    ArtifactBasicMetadata c2q = new ArtifactBasicMetadata("t:c:[2,4)");
    
    MetadataTreeNode nd1 = new MetadataTreeNode( d1, na1, d1 )
      .addQuery( c2q )
    ;
    MetadataTreeNode nb2 = new MetadataTreeNode( b2, na1, b2 )
      .addQuery( c1 )
    ;
    
    MetadataTreeNode nc2 = new MetadataTreeNode( c2, nd1, c2q );

    MetadataTreeNode nc1 = new MetadataTreeNode( c1, nb2, c1 );
    
    na1
      .addChild(nd1)
      .addChild(nb2)
    ;
    
    nd1
      .addChild(nc2)
    ;
    
    nb2
      .addChild(nc1)
    ;
    
    MetadataTreeNode.reNumber( na1, 1 );
    
    assertEquals( 1, na1.getId() );
    
    assertEquals( 2, nd1.getId() );
    
  }
  //----------------------------------------------------------------------
  public void testOptimization()
  throws SatException
  {
    title = "optimization test";
    System.out.println("\n\n==========================\n"+title+"\n");

    //       b:b:1
    //      / 
    // a:a:1       b:b:2
    //    \     /
    //     c:c:1
    //          \ b:b:1
    
    ArtifactMetadata mdaa1 = new ArtifactMetadata("a:a:1");
    ArtifactMetadata mdbb1 = new ArtifactMetadata("b:b:1");
    ArtifactMetadata mdbb2 = new ArtifactMetadata("b:b:2");
    ArtifactMetadata mdcc1 = new ArtifactMetadata("c:c:1");
    
    MetadataTreeNode aa1;
    MetadataTreeNode bb1;
    MetadataTreeNode cc1;
    MetadataTreeNode cc1bb1;
    MetadataTreeNode cc1bb2;
    
    aa1 = new MetadataTreeNode( mdaa1, null, mdaa1 );
    bb1 = new MetadataTreeNode( mdbb1, aa1, mdbb1 );
    aa1.addChild(bb1);
    cc1 = new MetadataTreeNode( mdcc1, aa1, mdcc1 );
    aa1.addChild(cc1);
    cc1bb1 = new MetadataTreeNode( mdbb1, cc1, mdbb1 );
    cc1.addChild( cc1bb1 );
    cc1bb2 = new MetadataTreeNode( mdbb2, cc1, mdbb2 );
    cc1.addChild( cc1bb2 );
    
    ss = (DefaultSatSolver) DefaultSatSolver.create( aa1 );
    
    List< Comparator<MetadataTreeNode>> comparators = new ArrayList<Comparator<MetadataTreeNode>>(2);
    comparators.add( new ClassicDepthComparator() );
    comparators.add( new ClassicVersionComparator() );
    
    Map<String, List<MetadataTreeNode>> buckets = new HashMap<String, List<MetadataTreeNode>>(128);
    DefaultSatSolver.fillBuckets( buckets, aa1 );
    DefaultSatSolver.sortBuckets( buckets, comparators );

    assertNotNull("no resulting map", buckets ); 
    assertEquals( "bad map size", 3, buckets.size() ); 
    
    System.out.println("optimized buckets: "+buckets);
    
    List<MetadataTreeNode> bbl = buckets.get("b:b");
    assertNotNull("no b:b list", bbl );
    assertEquals( "bad b:b list size", 2, bbl.size() ); 
    
    MetadataTreeNode first = bbl.get(0);
    assertNotNull("bad first element", first );
    assertEquals( "bad first element's GAV", "b:b:1::jar", first.getMd().getGAV() );
    assertEquals( "bad first element's depth", 1, first.getDepth() );
    
    MetadataTreeNode second = bbl.get(1);
    assertNotNull("bad second element", second );
    assertEquals( "bad second element's GAV", "b:b:2::jar", second.getMd().getGAV() );
    assertEquals( "bad second element's depth", 2, second.getDepth() );
  }
  //----------------------------------------------------------------------
  //
  // a1
  //    and (b1 or b2 or b3)
  //    and ((c1 and b1) or (c2 and (b2 or b3))
  //
  //----------------------------------------------------------------------
  public void testClassicResolution()
  throws SatException
  {
    title = "simplest 3-node tree";
    System.out.println("\n\n==========================\n"+title+"\n");
    
    MetadataTreeNode na1 = new MetadataTreeNode( a1, null, null )
      .addQuery(b1)
      .addQuery(c1)
    ;
    
    MetadataTreeNode nb1 = new MetadataTreeNode( b1, na1, b1 );
    MetadataTreeNode nb2 = new MetadataTreeNode( b2, na1, b1 );
    MetadataTreeNode nb3 = new MetadataTreeNode( b3, na1, b1 );
    
    MetadataTreeNode nc1 = new MetadataTreeNode( c1, na1, c1 )
      .addQuery(b1)
    ;
    MetadataTreeNode nc2 = new MetadataTreeNode( c2, na1, c1 )
      .addQuery(b1)
    ;
    
    na1
      .addChild(nb1)
      .addChild(nb2)
      .addChild(nb3)
      .addChild(nc1)
      .addChild(nc2)
    ;
    
    nc1
      .addChild(nb1)
    ;
    
    nc2
      .addChild(nb2)
      .addChild(nb3)
    ;

    ss = (DefaultSatSolver) DefaultSatSolver.create(na1);

    List<ArtifactMetadata> res = ss.solve();
    
    int m[] = ss._solver.model();

    System.out.print("model: " );
    for( int i=0; i<m.length; i++ )
      System.out.print(" "+m[i]);
    System.out.println("");

    assertNotNull( res );
    
    System.out.print("Result:");
    for( ArtifactMetadata md : res )
    {
      System.out.print(" "+md);
    }
    System.out.println("");

    assertEquals( 3, res.size() );
    
    assertTrue( res.contains( a1 ) );
    assertTrue( res.contains( b2 ) );
    assertTrue( res.contains( c2 ) );
  }
  //----------------------------------------------------------------------
  //       b:b:1 - c:c:2
  //      / 
  // a:a:1
  //      \     
  //       b:b:2 - c:c:1
  //----------------------------------------------------------------------
  public void testSingleVersionResolution()
  throws SatException
  {
    title = "testSingleVersionResolution";
    System.out.println("\n\n==========================\n"+title+"\n");
    
    MetadataTreeNode na1 = new MetadataTreeNode( a1, null, null )
      .addQuery(b1)
      .addQuery(b2)
    ;
    
    MetadataTreeNode nb1 = new MetadataTreeNode( b1, na1, b1 )
      .addQuery( c2 )
    ;
    MetadataTreeNode nb2 = new MetadataTreeNode( b2, na1, b2 )
      .addQuery( c1 )
    ;
    
    MetadataTreeNode nc2 = new MetadataTreeNode( c2, nb1, c2 );

    MetadataTreeNode nc1 = new MetadataTreeNode( c1, nb2, c1 );
    
    na1
      .addChild(nb1)
      .addChild(nb2)
    ;
    
    nb1
      .addChild(nc2)
    ;
    
    nb2
      .addChild(nc1)
    ;
    
    List<Comparator<MetadataTreeNode>> cl = new ArrayList<Comparator<MetadataTreeNode>>(2);
    cl.add( new ClassicDepthComparator() );
    cl.add( new ClassicVersionComparator() );

    ss = (DefaultSatSolver) DefaultSatSolver.create(na1);
    
    ss.applyPolicies( cl );

    List<ArtifactMetadata> res = ss.solve();
    
    int m[] = ss._solver.model();

    System.out.print("model: " );

    for( int i=0; i<m.length; i++ )
      System.out.print(" "+m[i]);
    System.out.println("");

    assertNotNull( res );
    
    System.out.print("Result:");
    for( ArtifactMetadata md : res )
    {
      System.out.print(" "+md);
    }
    System.out.println("");
    
    assertEquals( 3, res.size() );
    
    assertTrue( res.contains( a1 ) );
    assertTrue( res.contains( b2 ) );
    assertTrue( res.contains( c1 ) );
  }
  //----------------------------------------------------------------------
  //       b:b:1 - c:c:[2,4)
  //      / 
  // a:a:1
  //      \     
  //       b:b:2 - c:c:1
  //----------------------------------------------------------------------
  public void testStrictRangeResolution()
  throws SatException
  {
    title = "testStrictRangeResolution";
    System.out.println("\n\n==========================\n"+title+"\n");
    
    MetadataTreeNode na1 = new MetadataTreeNode( a1, null, null )
      .addQuery(b1)
      .addQuery(b2)
    ;
    
    ArtifactBasicMetadata c2q = new ArtifactBasicMetadata("t:c:[2,4)");
    
    MetadataTreeNode nb1 = new MetadataTreeNode( b1, na1, b1 )
      .addQuery( c2q )
    ;
    MetadataTreeNode nb2 = new MetadataTreeNode( b2, na1, b2 )
      .addQuery( c1 )
    ;
    
    MetadataTreeNode nc2 = new MetadataTreeNode( c2, nb1, c2q );

    MetadataTreeNode nc1 = new MetadataTreeNode( c1, nb2, c1 );
    
    na1
      .addChild(nb1)
      .addChild(nb2)
    ;
    
    nb1
      .addChild(nc2)
    ;
    
    nb2
      .addChild(nc1)
    ;
    
    List<Comparator<MetadataTreeNode>> cl = new ArrayList<Comparator<MetadataTreeNode>>(2);
    cl.add( new ClassicDepthComparator() );
    cl.add( new ClassicVersionComparator() );

    ss = (DefaultSatSolver) DefaultSatSolver.create(na1);
    
    ss.applyPolicies( cl );

    List<ArtifactMetadata> res = ss.solve();
    
    int m[] = ss._solver.model();

    System.out.print("model: " );

    for( int i=0; i<m.length; i++ )
      System.out.print(" "+m[i]);
    System.out.println("");

    assertNotNull( res );
    
    System.out.print("Result:");
    for( ArtifactMetadata md : res )
    {
      System.out.print(" "+md);
    }
    System.out.println("");
    
    assertEquals( 3, res.size() );
    
    assertTrue( res.contains( a1 ) );
    assertTrue( res.contains( b2 ) );
    assertTrue( res.contains( c1 ) );
  }
  //----------------------------------------------------------------------
  //       d:d:1 - c:c:[2,4)
  //      / 
  // a:a:1
  //      \     
  //       b:b:2 - c:c:1
  //----------------------------------------------------------------------
  public void testStrictRangeResolution2()
  throws SatException
  {
    title = "testStrictRangeResolution2";
    System.out.println("\n\n==========================\n"+title+"\n");
    
    MetadataTreeNode na1 = new MetadataTreeNode( a1, null, null )
      .addQuery(d1)
      .addQuery(b2)
    ;
    
    ArtifactBasicMetadata c2q = new ArtifactBasicMetadata("t:c:[2,4)");
    
    MetadataTreeNode nd1 = new MetadataTreeNode( d1, na1, d1 )
      .addQuery( c2q )
    ;
    MetadataTreeNode nb2 = new MetadataTreeNode( b2, na1, b2 )
      .addQuery( c1 )
    ;
    
    MetadataTreeNode nc2 = new MetadataTreeNode( c2, nd1, c2q );

    MetadataTreeNode nc1 = new MetadataTreeNode( c1, nb2, c1 );
    
    na1
      .addChild(nd1)
      .addChild(nb2)
    ;
    
    nd1
      .addChild(nc2)
    ;
    
    nb2
      .addChild(nc1)
    ;
    
    List<Comparator<MetadataTreeNode>> cl = new ArrayList<Comparator<MetadataTreeNode>>(2);
    cl.add( new ClassicDepthComparator() );
    cl.add( new ClassicVersionComparator() );

    ss = (DefaultSatSolver) DefaultSatSolver.create(na1);
    
    ss.applyPolicies( cl );

    List<ArtifactMetadata> res = ss.solve();
    
    int m[] = ss._solver.model();

    System.out.print("model: " );

    for( int i=0; i<m.length; i++ )
      System.out.print(" "+m[i]);
    System.out.println("");

    assertNotNull( res );
    
    System.out.print("Result:");
    for( ArtifactMetadata md : res )
    {
      System.out.print(" "+md);
    }
    System.out.println("");
    
    assertEquals( 4, res.size() );
    
    assertTrue( res.contains( a1 ) );
    assertTrue( res.contains( d1 ) );
    assertTrue( res.contains( b2 ) );
    assertTrue( res.contains( c2 ) );
  }
  
  //----------------------------------------------------------------------
  //       d:d:1 - c:c:[2,4)
  //      / 
  // a:a:1
  //      \     
  //       b:b:2 - c:c:1
  //----------------------------------------------------------------------
  public void testSolveAsTree()
  throws SatException, IOException
  {
    title = "testSolveAsTree";
    System.out.println("\n\n==========================\n"+title+"\n");
    
    MetadataTreeNode na1 = new MetadataTreeNode( a1, null, null )
      .addQuery(d1)
      .addQuery(b2)
    ;
    
    ArtifactBasicMetadata c2q = new ArtifactBasicMetadata("t:c:[2,4)");
    
    MetadataTreeNode nd1 = new MetadataTreeNode( d1, na1, d1 )
      .addQuery( c2q )
    ;
    MetadataTreeNode nb2 = new MetadataTreeNode( b2, na1, b2 )
      .addQuery( c1 )
    ;
    
    MetadataTreeNode nc2 = new MetadataTreeNode( c2, nd1, c2q );

    MetadataTreeNode nc1 = new MetadataTreeNode( c1, nb2, c1 );
    
    na1
      .addChild(nd1)
      .addChild(nb2)
    ;
    
    nd1
      .addChild(nc2)
    ;
    
    nb2
      .addChild(nc1)
    ;
    
    List<Comparator<MetadataTreeNode>> cl = new ArrayList<Comparator<MetadataTreeNode>>(2);
    cl.add( new ClassicDepthComparator() );
    cl.add( new ClassicVersionComparator() );

    ss = (DefaultSatSolver) DefaultSatSolver.create(na1);
    
    ss.applyPolicies( cl );

    MetadataTreeNode res = ss.solveAsTree();
    
    assertNotNull( res );
    
    MetadataTreeNode.showNode( res, 0 );
    
    assertEquals( 4, res.countNodes() );
    
  }
  //----------------------------------------------------------------------
  //----------------------------------------------------------------------
}
