package simpledb.unittest;


import java.io.IOException;
import java.util.*;
import junit.framework.JUnit4TestAdapter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import simpledb.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * We reserve more heavy-duty insertion testing for HeapFile and HeapPage.
 * This suite is superficial.
 */
public class DeleteTest {

  private DbIterator scan1;
  private DbIterator scan2;
  private HeapFile empty;
  private TransactionId tid;
  private static final String emptyPath = 
    "src/simpledb/unittest/testdata/empty.dat";

  /**
   * Initialize each unit test
   */
  @Before public void setUp() throws Exception {
    this.scan1 = Utility.createTupleList(2, 
        new int[] { 1, 2,
                    1, 4,
                    1, 6,
                    3, 2,
                    3, 4,
                    3, 6,
                    5, 7 });
    this.scan2 = Utility.createTupleList(2, 
        new int[] { 1, 2,
                    1, 4,
                    1, 6,
                    5, 7 });
    this.empty = Utility.createEmptyHeapFile(emptyPath, 2);
    this.tid = new TransactionId();

  }

  /**
   * Unit test for Delete.getTupleDesc()
   */
  @Test public void getTupleDesc() throws Exception {
      Delete op = new Delete(tid, scan1);
    
    TupleDesc expected = Utility.getTupleDesc(1);
    TupleDesc actual = op.getTupleDesc();
    assertTrue(expected.equals(actual));
  }

  /**
   * Unit test for Delete.getNext()
   */
  @Test public void getNext() throws Exception {
      Insert insop = new Insert(tid, scan1, empty.id()); 
      insop.open();
    assertTrue(Utility.compareTuples(
          Utility.getHeapTuple(7, 1), // the length of scan1 
          insop.getNext()));

    // we should fit on one page
    assertEquals(1, empty.numPages());

      SeqScan ss = new SeqScan(tid, empty.id());
      Predicate p = new Predicate(0,
                                  Predicate.Op.EQUALS,
                                  new IntField(new Integer(3)));
      Filter f = new Filter(p, ss);
      Delete op = new Delete(tid, f);
      
      op.open();
      assertTrue(Utility.compareTuples(
                                       Utility.getHeapTuple(3, 1), // the length of scan1 
                                       op.getNext()));

    // we should fit on one page
    assertEquals(1, empty.numPages());

    Database.getBufferPool().flushAllPages();

    ss = new SeqScan(tid, empty.id());
    
    ss.open();
    Utility.compareDbIterators(scan2, ss);
  }

  /**
   * JUnit suite target
   */
  public static junit.framework.Test suite() {
    return new JUnit4TestAdapter(DeleteTest.class);
  }
}


