/**
 * Copyright (C) 2009-2013 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 as published by
 * the Free Software Foundation, either version 3 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 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.bug1043377;

import com.akiban.ais.model.Index;
import com.akiban.ais.model.UserTable;
import com.akiban.server.service.config.ConfigurationService;
import com.akiban.server.service.listener.ListenerService;
import com.akiban.server.service.lock.LockService;
import com.akiban.server.service.servicemanager.GuicedServiceManager;
import com.akiban.server.service.session.Session;
import com.akiban.server.service.tree.TreeService;
import com.akiban.server.store.PersistitStore;
import com.akiban.server.store.SchemaManager;
import com.akiban.server.store.Store;
import com.akiban.server.test.it.ITBase;
import com.google.inject.Inject;
import org.junit.Test;
import java.util.Collection;
import java.util.Map;

import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

public final class FailureDuringIndexBuildingIT extends ITBase {
    private static final AssertionError EXPECTED_EXCEPTION = new AssertionError();

    @Override
    protected GuicedServiceManager.BindingsConfigurationProvider serviceBindingsProvider() {
        return super.serviceBindingsProvider().bind(Store.class, ThrowsAfterBuildIndexesStore.class);
    }

    @Override
    protected Map<String, String> startupConfigProperties() {
        return uniqueStartupConfigProperties(getClass());
    }

    @Test
    public void injectedFailure() throws Throwable {
        final String SCHEMA = "test";
        final String TABLE = "t1";
        final String INDEX = "lat_lon";
        int tid = createTable(SCHEMA, TABLE, "userID int not null primary key, lat decimal(11,7), lon decimal(11,7)");
        writeRows(
                createNewRow(tid, 1L, "20.5", "11.0"),
                createNewRow(tid, 2L, "90.0", "90.0"),
                createNewRow(tid, 3L, "60.2", "5.34")
        );

        try {
            createIndex(SCHEMA, TABLE, INDEX, "lat", "lon");
            fail("Expected exception");
        } catch(Throwable t) {
            if(t != EXPECTED_EXCEPTION) {
                throw t;
            }
        }

        UserTable table = getUserTable(SCHEMA, TABLE);
        assertNull("Index should not be present", table.getIndex(INDEX));
    }

    public static class ThrowsAfterBuildIndexesStore extends PersistitStore {
        @Inject
        public ThrowsAfterBuildIndexesStore(TreeService treeService, ConfigurationService configService,
                                            SchemaManager schemaManager, LockService lockService, ListenerService listenerService) {
            super(treeService, configService, schemaManager, lockService, listenerService);
        }

        @Override
        public void buildIndexes(Session session, Collection<? extends Index> indexes) {
            super.buildIndexes(session, indexes);
            throw EXPECTED_EXCEPTION;
        }
    }
}

@@ -888,521 +888,229 @@
 ice.
-config.ConfigurationService;%0Aimport com.akiban.server.service.listener.ListenerService;%0Aimport com.akiban.server.service.lock.LockService;%0Aimport com.akiban.server.service.servicemanager.GuicedServiceManager;%0Aimport com.akiban.server.service.session.Session;%0Aimport com.akiban.server.service.tree.TreeService;%0Aimport com.akiban.server.store.PersistitStore;%0Aimport com.akiban.server.store.SchemaManager;%0Aimport com.akiban.server.store.Store;%0Aimport com.akiban.server.test.it.ITBase;%0Aimport com.google.inject.Inject
+listener.ListenerService;%0Aimport com.akiban.server.service.listener.TableListener;%0Aimport com.akiban.server.service.session.Session;%0Aimport com.akiban.server.test.it.ITBase;%0Aimport org.junit.After;%0Aimport org.junit.Before
 ;%0Aim
@@ -1326,16 +1326,41 @@
  ITBase 
+implements TableListener 
 %7B%0A    pr
@@ -1446,208 +1446,297 @@
    @
-Override%0A    protected GuicedServiceManager.BindingsConfigurationProvider serviceBindingsProvider() %7B%0A        return super.serviceBindingsProvider().bind(Store.class, ThrowsAfterBuildIndexesStore.clas
+Before%0A    public void registerListener() %7B%0A        serviceManager().getServiceByClass(ListenerService.class).registerTableListener(this);%0A    %7D%0A%0A    @After%0A    public void deregisterListener() %7B%0A        serviceManager().getServiceByClass(ListenerService.class).deregisterTableListener(thi
 s);%0A
@@ -2751,335 +2751,195 @@
  %7D%0A%0A
+%0A
     
-public static class ThrowsAfterBuildIndexesStore extends PersistitStore %7B
+//%0A    // TableListener
 %0A    
+//%0A%0A
     @
-Inject%0A        public ThrowsAfterBuildIndexesStore(TreeService treeService, ConfigurationService configService,
+Override%0A    public void onCreate(Session session, UserTable table) %7B
 %0A    
-  
+%7D%0A%0A
     
-                                  SchemaManager schemaManager, LockService lockService, ListenerService listenerServic
+@Override%0A    public void onDrop(Session session, UserTable tabl
 e) %7B
@@ -2947,111 +2947,111 @@
     
+%7D%0A%0A
     
-    super(treeService, configService, schemaManager, lockService, listenerService);%0A    
+@Override%0A    public void onTruncate(Session session, UserTable table, boolean isFast) %7B%0A
     %7D%0A%0A
-    
     
@@ -3060,20 +3060,16 @@
 verride%0A
-    
     publ
@@ -3076,28 +3076,29 @@
 ic void 
-build
+onCreate
 Index
-es
 (Session
@@ -3158,97 +3158,138 @@
     
-    super.buildIndexes(session, indexes);%0A            throw EXPECTED_EXCEPTION;%0A        %7D
+throw EXPECTED_EXCEPTION;%0A    %7D%0A%0A    @Override%0A    public void onDropIndex(Session session, Collection%3C? extends Index%3E indexes) %7B
 %0A   

Use ListenerService instead of extending PersistitStore