/**
 * 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.hcatalog.common;

import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaStore;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.AlreadyExistsException;
import org.apache.hadoop.hive.metastore.api.Database;
import org.apache.hadoop.hive.metastore.api.FieldSchema;
import org.apache.hadoop.hive.metastore.api.InvalidObjectException;
import org.apache.hadoop.hive.metastore.api.MetaException;
import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
import org.apache.hadoop.hive.metastore.api.SerDeInfo;
import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hcatalog.NoExitSecurityManager;
import org.apache.hcatalog.cli.SemanticAnalysis.HCatSemanticAnalyzer;
import org.apache.thrift.TException;
import org.junit.AfterClass;
import org.junit.BeforeClass;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.security.auth.login.LoginException;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TestHiveClientCache {

    private static final Logger LOG = LoggerFactory.getLogger(TestHiveClientCache.class);
    final HiveConf hiveConf = new HiveConf();

    @BeforeClass
    public static void setUp() throws Exception {
    }

    @AfterClass
    public static void tearDown() throws Exception {
    }

    @Test
    public void testCacheHit() throws IOException, MetaException, LoginException {

        HiveClientCache cache = new HiveClientCache(1000);
        HiveMetaStoreClient client = cache.get(hiveConf);
        assertNotNull(client);
        client.close(); // close shouldn't matter

        // Setting a non important configuration should return the same client only
        hiveConf.setIntVar(HiveConf.ConfVars.DYNAMICPARTITIONMAXPARTS, 10);
        HiveMetaStoreClient client2 = cache.get(hiveConf);
        assertNotNull(client2);
        assertEquals(client, client2);
        client2.close();
    }

    @Test
    public void testCacheMiss() throws IOException, MetaException, LoginException {
        HiveClientCache cache = new HiveClientCache(1000);
        HiveMetaStoreClient client = cache.get(hiveConf);
        assertNotNull(client);

        // Set different uri as it is one of the criteria deciding whether to return the same client or not
        hiveConf.setVar(HiveConf.ConfVars.METASTOREURIS, " "); // URIs are checked for string equivalence, even spaces make them different
        HiveMetaStoreClient client2 = cache.get(hiveConf);
        assertNotNull(client2);
        assertNotSame(client, client2);
    }

    /**
     * Check that a new client is returned for the same configuration after the expiry time.
     * Also verify that the expiry time configuration is honoured
     */
    @Test
    public void testCacheExpiry() throws IOException, MetaException, LoginException, InterruptedException {
        HiveClientCache cache = new HiveClientCache(1);
        HiveClientCache.CacheableHiveMetaStoreClient client = (HiveClientCache.CacheableHiveMetaStoreClient) cache.get(hiveConf);
        assertNotNull(client);

        Thread.sleep(2500);
        HiveMetaStoreClient client2 = cache.get(hiveConf);
        client.close();
        assertTrue(client.isClosed()); // close() after *expiry time* and *a cache access* should  have tore down the client

        assertNotNull(client2);
        assertNotSame(client, client2);
    }

    /**
     * Check that a *new* client is created if asked from different threads even with
     * the same hive configuration
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @Test
    public void testMultipleThreadAccess() throws ExecutionException, InterruptedException {
        final HiveClientCache cache = new HiveClientCache(1000);

        class GetHiveClient implements Callable<HiveMetaStoreClient> {
            @Override
            public HiveMetaStoreClient call() throws IOException, MetaException, LoginException {
                return cache.get(hiveConf);
            }
        }

        ExecutorService executor = Executors.newFixedThreadPool(2);

        Callable<HiveMetaStoreClient> worker1 = new GetHiveClient();
        Callable<HiveMetaStoreClient> worker2 = new GetHiveClient();
        Future<HiveMetaStoreClient> clientFuture1 = executor.submit(worker1);
        Future<HiveMetaStoreClient> clientFuture2 = executor.submit(worker2);
        HiveMetaStoreClient client1 = clientFuture1.get();
        HiveMetaStoreClient client2 = clientFuture2.get();
        assertNotNull(client1);
        assertNotNull(client2);
        assertNotSame(client1, client2);
    }

    @Test
    public void testCloseAllClients() throws IOException, MetaException, LoginException {
        final HiveClientCache cache = new HiveClientCache(1000);
        HiveClientCache.CacheableHiveMetaStoreClient client1 = (HiveClientCache.CacheableHiveMetaStoreClient) cache.get(hiveConf);
        hiveConf.setVar(HiveConf.ConfVars.METASTOREURIS, " "); // URIs are checked for string equivalence, even spaces make them different
        HiveClientCache.CacheableHiveMetaStoreClient client2 = (HiveClientCache.CacheableHiveMetaStoreClient) cache.get(hiveConf);
        cache.closeAllClientsQuietly();
        assertTrue(client1.isClosed());
        assertTrue(client2.isClosed());
    }

    /**
     * Test that a long table name actually breaks the HMSC. Subsequently check that isOpen() reflects
     * and tells if the client is broken
     */
    @Test
    public void testHMSCBreakability() throws IOException, MetaException, LoginException, TException, AlreadyExistsException,
            InvalidObjectException, NoSuchObjectException, InterruptedException {
        // Setup
        LocalMetaServer metaServer = new LocalMetaServer();
        metaServer.start();

        final HiveClientCache cache = new HiveClientCache(1000);
        HiveClientCache.CacheableHiveMetaStoreClient client =
                (HiveClientCache.CacheableHiveMetaStoreClient) cache.get(metaServer.getHiveConf());

        assertTrue(client.isOpen());

        final String DB_NAME = "test_db";
        final String LONG_TABLE_NAME = "long_table_name_" + new BigInteger(200, new Random()).toString(2);

        try {
            client.dropTable(DB_NAME, LONG_TABLE_NAME);
        } catch (Exception e) {
        }
        try {
            client.dropDatabase(DB_NAME);
        } catch (Exception e) {
        }

        client.createDatabase(new Database(DB_NAME, "", null, null));

        List<FieldSchema> fields = new ArrayList<FieldSchema>();
        fields.add(new FieldSchema("colname", org.apache.hadoop.hive.serde.Constants.STRING_TYPE_NAME, ""));
        Table tbl = new Table();
        tbl.setDbName(DB_NAME);
        tbl.setTableName(LONG_TABLE_NAME);
        StorageDescriptor sd = new StorageDescriptor();
        sd.setCols(fields);
        tbl.setSd(sd);
        sd.setSerdeInfo(new SerDeInfo());

        // Break the client
        try {
            client.createTable(tbl);
            fail("Exception was expected while creating table with long name");
        } catch (Exception e) {
        }

        assertFalse(client.isOpen());
        metaServer.shutDown();
    }

    private static class LocalMetaServer implements Runnable {
        public final int MS_PORT = 20101;
        private final HiveConf hiveConf;
        private final SecurityManager securityManager;
        public final static int WAIT_TIME_FOR_BOOTUP = 30000;

        public LocalMetaServer() {
            securityManager = System.getSecurityManager();
            System.setSecurityManager(new NoExitSecurityManager());
            hiveConf = new HiveConf(TestHiveClientCache.class);
            hiveConf.set("hive.metastore.local", "false");
            hiveConf.setVar(HiveConf.ConfVars.METASTOREURIS, "thrift://localhost:"
                    + MS_PORT);
            hiveConf.setIntVar(HiveConf.ConfVars.METASTORETHRIFTRETRIES, 3);
            hiveConf.set(HiveConf.ConfVars.SEMANTIC_ANALYZER_HOOK.varname,
                    HCatSemanticAnalyzer.class.getName());
            hiveConf.set(HiveConf.ConfVars.PREEXECHOOKS.varname, "");
            hiveConf.set(HiveConf.ConfVars.POSTEXECHOOKS.varname, "");
            hiveConf.set(HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname,
                    "false");
            System.setProperty(HiveConf.ConfVars.PREEXECHOOKS.varname, " ");
            System.setProperty(HiveConf.ConfVars.POSTEXECHOOKS.varname, " ");
        }

        public void start() throws InterruptedException {
            Thread thread = new Thread(this);
            thread.start();
            Thread.sleep(WAIT_TIME_FOR_BOOTUP); // Wait for the server to bootup
        }

        @Override
        public void run() {
            try {
                HiveMetaStore.main(new String[]{"-v", "-p", String.valueOf(MS_PORT)});
            } catch (Throwable t) {
                LOG.error("Exiting. Got exception from metastore: ", t);
            }
        }

        public HiveConf getHiveConf() {
            return hiveConf;
        }

        public void shutDown() {
            System.setSecurityManager(securityManager);
        }
    }
}
