/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License;
 * you may not use this file except in compliance with the Elastic License.
 */
package org.elasticsearch.xpack.security;

import org.elasticsearch.action.bulk.byscroll.BulkByScrollResponse;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.index.reindex.ReindexAction;
import org.elasticsearch.index.reindex.ReindexPlugin;
import org.elasticsearch.index.reindex.UpdateByQueryAction;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.test.SecurityIntegTestCase;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

public class ReindexWithSecurityIT extends SecurityIntegTestCase {


    @Override
    protected Collection<Class<? extends Plugin>> nodePlugins() {
        Collection<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins());
        plugins.add(ReindexPlugin.class);
        return Collections.unmodifiableCollection(plugins);
    }

    @Override
    protected Collection<Class<? extends Plugin>> transportClientPlugins() {
        Collection<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins());
        plugins.add(ReindexPlugin.class);
        return Collections.unmodifiableCollection(plugins);
    }

    @Override
    protected Settings externalClusterClientSettings() {
        Settings.Builder builder = Settings.builder().put(super.externalClusterClientSettings());
        builder.put(NetworkModule.TRANSPORT_TYPE_KEY, Security.NAME4);
        builder.put(Security.USER_SETTING.getKey(), "test_admin:changeme");
        return builder.build();
    }

    public void testDeleteByQuery() {
        createIndicesWithRandomAliases("test1", "test2", "test3");

        BulkByScrollResponse response = DeleteByQueryAction.INSTANCE.newRequestBuilder(client()).source("test1", "test2").get();
        assertNotNull(response);

        response = DeleteByQueryAction.INSTANCE.newRequestBuilder(client()).source("test*").get();
        assertNotNull(response);

        IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
                () -> DeleteByQueryAction.INSTANCE.newRequestBuilder(client()).source("test1", "index1").get());
        assertEquals("no such index", e.getMessage());
    }

    public void testUpdateByQuery() {
        createIndicesWithRandomAliases("test1", "test2", "test3");

        BulkByScrollResponse response = UpdateByQueryAction.INSTANCE.newRequestBuilder(client()).source("test1", "test2").get();
        assertNotNull(response);

        response = UpdateByQueryAction.INSTANCE.newRequestBuilder(client()).source("test*").get();
        assertNotNull(response);

        IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
                () -> UpdateByQueryAction.INSTANCE.newRequestBuilder(client()).source("test1", "index1").get());
        assertEquals("no such index", e.getMessage());
    }

    public void testReindex() {
        createIndicesWithRandomAliases("test1", "test2", "test3", "dest");

        BulkByScrollResponse response = ReindexAction.INSTANCE.newRequestBuilder(client()).source("test1", "test2")
                .destination("dest").get();
        assertNotNull(response);

        response = ReindexAction.INSTANCE.newRequestBuilder(client()).source("test*").destination("dest").get();
        assertNotNull(response);

        IndexNotFoundException e = expectThrows(IndexNotFoundException.class,
                () -> ReindexAction.INSTANCE.newRequestBuilder(client()).source("test1", "index1").destination("dest").get());
        assertEquals("no such index", e.getMessage());
    }
}

@@ -503,24 +503,76 @@
 dException;%0A
+import org.elasticsearch.index.query.QueryBuilders;%0A
 import org.e
@@ -2161,32 +2161,49 @@
 uilder(client())
+%0A                
 .source(%22test1%22,
@@ -2203,32 +2203,104 @@
 test1%22, %22test2%22)
+%0A                .filter(QueryBuilders.matchAllQuery())%0A                
 .get();%0A        
@@ -2400,32 +2400,121 @@
 lient())
-.source(%22test*%22)
+%0A                .source(%22test*%22)%0A                .filter(QueryBuilders.matchAllQuery())%0A                
 .get();%0A
@@ -2695,32 +2695,57 @@
 uilder(client())
+%0A                        
 .source(%22test1%22,
@@ -2746,32 +2746,120 @@
 est1%22, %22index1%22)
+%0A                        .filter(QueryBuilders.matchAllQuery())%0A                        
 .get());%0A       

Set required euery on delete-by-query request