/**
 * Copyright (C) 2011 Akiban Technologies Inc.
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 */

package com.akiban.server.test.it.bugs.bug701580;

import com.akiban.ais.model.Index;
import com.akiban.ais.model.UserTable;
import com.akiban.server.test.it.ITBase;
import org.junit.Test;

import java.util.HashSet;
import java.util.Set;

import static org.junit.Assert.*;

public final class SpuriousDuplicateKeyIT extends ITBase {
    @Test
    public void simpleOnce() throws Exception {
        simpleTestCase();
    }

    @Test
    public void simpleTwice() throws Exception {
        simpleTestCase();
        simpleTestCase();
    }

    private void simpleTestCase() throws Exception {
        createTable("test", "t1", "bid1 int, token varchar(64), primary key(bid1), key (token)");
        int t2 = createTable("test", "t2", "bid int, theme varchar(64), primary key (bid), unique key (theme)");

        confirmIds("t1", 1, 2, 2);
        confirmIds("t2", 1, 2, 2);

        writeRows(
                createNewRow(t2, 1, "0"),
                createNewRow(t2, 2, "1"),
                createNewRow(t2, 3, "2")
        );
        dropAllTables();
    }

    @Test
    public void indexIdsLocalToGroup() throws Exception {
        createTable("test", "t1", "bid1 int, token varchar(64), primary key(bid1), key (token)");

        createTable("test", "t2", "bid int, theme varchar(64), primary key (bid), unique key (theme)");
        createTable("test", "t3", "id int key, bid_id int, "
                +"CONSTRAINT __akiban_fk FOREIGN KEY (bid_id) REFERENCES t2 (bid)");

        confirmIds("t1", 1, 2, 2);
        confirmIds("t2", 1, 2, 4);
        confirmIds("t3", 3, 2, 4);
    }

    /**
     * Confirm that the given table has sequential index IDs starting from the given number, and that its
     * group table has all those indexes as well.
     * @param tableName the table to start at
     * @param startingAt the index to start at
     * @param expectedUIndexes how many indexes you expect on the user table
     * @param expectedGIndexes how many indexes you expect on the group table
     * @throws Exception if there's a problem!
     */
    private void confirmIds(String tableName, int startingAt, int expectedUIndexes, int expectedGIndexes)
            throws Exception {
        UserTable uTable = ddl().getAIS(session()).getUserTable("test", tableName);

        Set<Integer> expectedUTableIds = new HashSet<Integer>();
        Set<Integer> actualUTableIds = new HashSet<Integer>();
        for (Index index : uTable.getIndexes()) {
            actualUTableIds.add(index.getIndexId());
            expectedUTableIds.add( expectedUTableIds.size() + startingAt );
        }

        Set<Integer> actualGTableIds = new HashSet<Integer>();
        for(Index index : uTable.getGroup().getGroupTable().getIndexes()) {
            actualGTableIds.add(index.getIndexId());
        }

        assertEquals("uTable index count", expectedUIndexes, actualUTableIds.size());
        assertEquals("actualUTableIds", actualUTableIds, expectedUTableIds);

        if(!actualGTableIds.containsAll(actualUTableIds)) {
            Set<Integer> missing = new HashSet<Integer>(actualUTableIds);
            missing.removeAll(actualGTableIds);
            fail(String.format("missing %s: %s doesn't contain all of %s", missing, actualGTableIds, actualUTableIds));
        }
        assertEquals("gTable index count", expectedGIndexes, actualGTableIds.size());
    }
}

@@ -1280,32 +1280,41 @@
  %22t1%22, %22bid1 int
+ not null
 , token varchar(
@@ -1331,37 +1331,77 @@
 ry key(bid1)
-, key (
+%22);%0A        createIndex(%22test%22, %22t1%22, %22token%22, %22
 token
-)
 %22);%0A        
@@ -1435,32 +1435,41 @@
 , %22t2%22, %22bid int
+ not null
 , theme varchar(
@@ -1490,37 +1490,32 @@
 ey (bid), unique
- key 
 (theme)%22);%0A%0A    
@@ -1879,16 +1879,25 @@
 bid1 int
+ not null
 , token 
@@ -1930,21 +1930,61 @@
 id1)
-, key (
+%22);%0A        createIndex(%22test%22, %22t1%22, %22token%22, %22
 token
-)
 %22);%0A
@@ -2026,16 +2026,25 @@
 %22bid int
+ not null
 , theme 
@@ -2082,20 +2082,16 @@
  unique 
-key 
 (theme)%22
@@ -2135,16 +2135,33 @@
 %22id int 
+not null primary 
 key, bid
@@ -2170,17 +2170,20 @@
 d int, %22
-%0A
++%0A  
         
@@ -2194,32 +2194,19 @@
     
-+%22CONSTRAINT __akiban_fk
+  %22GROUPING
  FOR
@@ -2241,24 +2241,84 @@
  t2 (bid)%22);
+%0A        createIndex(%22test%22, %22t3%22, %22__akiban_fk%22, %22bid_id%22);
 %0A%0A        co

Fix SpuriousDuplicateKeyIT schemas