/**
 * 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.hbase.snapshot;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import org.apache.hcatalog.hbase.SkeletonHBaseTest;
import org.junit.Assert;
import org.junit.Test;

public class TestIDGenerator extends SkeletonHBaseTest{

    @Test
    public void testIDGeneration() throws Exception {

        int port = getHbaseConf().getInt("hbase.zookeeper.property.clientPort", 2181);
        String servers = getHbaseConf().get("hbase.zookeeper.quorum");
        String[] splits = servers.split(",");
        StringBuffer sb = new StringBuffer();
        for(String split : splits){
            sb.append(split);
            sb.append(':');
            sb.append(port);
        }
        ZKUtil zkutil = new ZKUtil(sb.toString(), "/rm_base");

        String tableName = "myTable";
        long initId = zkutil.nextId(tableName);
        for (int i=0; i<10; i++) {
            long id = zkutil.nextId(tableName);
            Assert.assertEquals(initId + (i + 1), id);
        }
    }

    @Test
    public void testMultipleClients() throws InterruptedException{

        int port = getHbaseConf().getInt("hbase.zookeeper.property.clientPort", 2181);
        String servers = getHbaseConf().get("hbase.zookeeper.quorum");
        String[] splits = servers.split(",");
        StringBuffer sb = new StringBuffer();
        for(String split : splits){
            sb.append(split);
            sb.append(':');
            sb.append(port);
        }

        ArrayList<IDGenClient> clients = new ArrayList<IDGenClient>();

        for(int i =0; i < 5; i++){
            IDGenClient idClient = new IDGenClient(sb.toString(), "/rm_base", 10, "testTable");
            clients.add(idClient);
        }

        for(IDGenClient idClient : clients){
            idClient.run();
        }

        for(IDGenClient idClient : clients){
            idClient.join();
        }

        HashMap<Long, Long> idMap = new HashMap<Long, Long>();
        for(IDGenClient idClient : clients){
            idMap.putAll(idClient.getIdMap());
        }

        ArrayList<Long> keys = new ArrayList<Long>(idMap.keySet());
        Collections.sort(keys);
        int startId = 1;
        for(Long key: keys){
            Long id = idMap.get(key);
            System.out.println("Key: " + key + " Value "+ id);
            assertTrue(id == startId);
            startId++;

        }
    }
}
