/**
 * 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 java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hcatalog.hbase.SkeletonHBaseTest;
import org.junit.Assert;
import org.junit.Test;

public class TestRevisionManagerEndpoint extends SkeletonHBaseTest {

  static {
    // test case specific mini cluster settings
    testConf = new Configuration(false);
    testConf.setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
        "org.apache.hcatalog.hbase.snapshot.RevisionManagerEndpoint",
        "org.apache.hadoop.hbase.coprocessor.GenericEndpoint");
    testConf.set(RMConstants.REVISION_MGR_ENDPOINT_IMPL_CLASS, MockRM.class.getName());
  }

  /**
   * Mock implementation to test the protocol/serialization
   */
  public static class MockRM implements RevisionManager {

    private static class Invocation {
      Invocation(String methodName, Object ret, Object... args) {
          this.methodName = methodName;
          this.args = args;
          this.ret = ret;
      }

      String methodName;
      Object[] args;
      Object ret;

      private static boolean equals(Object obj1, Object obj2) {
        if (obj1 == obj2) return true;
        if (obj1 == null || obj2 == null) return false;
        if (obj1 instanceof Transaction || obj1 instanceof TableSnapshot) {
          return obj1.toString().equals(obj2.toString());
        }
        return obj1.equals(obj2);
      }

      @Override
      public boolean equals(Object obj) {
        Invocation other = (Invocation)obj;
        if (this == other) return true;
        if (other == null) return false;
        if (this.args != other.args) {
          if (this.args == null || other.args == null) return false;
          if (this.args.length != other.args.length) return false;
          for (int i=0; i<args.length; i++) {
            if (!equals(this.args[i], other.args[i])) return false;
          }
        }
        return equals(this.ret, other.ret);
      }

      @Override
      public String toString() {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).
            append("method", this.methodName).
            append("args", this.args).
            append("returns", this.ret).
            toString();
      }
    }

    final static String DEFAULT_INSTANCE = "default";
    final static Map<String, MockRM> INSTANCES = new ConcurrentHashMap<String, MockRM>();
    Invocation lastCall;
    boolean isOpen = false;

    private <T extends Object> T recordCall(T result, Object...args) {
      StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
      lastCall = new Invocation(stackTrace[2].getMethodName(), result, args);
      return result;
    }

    @Override
    public void initialize(Configuration conf) {
      if(!INSTANCES.containsKey(DEFAULT_INSTANCE))
        INSTANCES.put(DEFAULT_INSTANCE, this);
    }

    @Override
    public void open() throws IOException {
      isOpen = true;
    }

    @Override
    public void close() throws IOException {
      isOpen = false;
    }

    @Override
    public void createTable(String table, List<String> columnFamilies) throws IOException {
    }

    @Override
    public void dropTable(String table) throws IOException {
    }

    @Override
    public Transaction beginWriteTransaction(String table,
        List<String> families) throws IOException {
      return recordCall(null, table, families);
    }

    @Override
    public Transaction beginWriteTransaction(String table,
      List<String> families, long keepAlive) throws IOException {
      return recordCall(null, table, families, keepAlive);
    }

    @Override
    public void commitWriteTransaction(Transaction transaction)
        throws IOException {
    }

    @Override
    public void abortWriteTransaction(Transaction transaction)
        throws IOException {
    }

    @Override
    public List<FamilyRevision> getAbortedWriteTransactions(String table,
        String columnFamily) throws IOException {
      return null;
    }

    @Override
    public TableSnapshot createSnapshot(String tableName)
        throws IOException {
      return null;
    }

    @Override
    public TableSnapshot createSnapshot(String tableName, long revision)
        throws IOException {
      TableSnapshot ret = new TableSnapshot(tableName, new HashMap<String, Long>(), revision);
      return recordCall(ret, tableName, revision);
    }

    @Override
    public void keepAlive(Transaction transaction) throws IOException {
      recordCall(null, transaction);
    }
  }

  @Test
  public void testRevisionManagerProtocol() throws Throwable {

    Configuration conf = getHbaseConf();
    RevisionManager rm = RevisionManagerFactory.getOpenedRevisionManager(
        RevisionManagerEndpointClient.class.getName(), conf);

    MockRM mockImpl = MockRM.INSTANCES.get(MockRM.DEFAULT_INSTANCE);
    Assert.assertNotNull(mockImpl);
    Assert.assertTrue(mockImpl.isOpen);

    Transaction t = new Transaction("t1", Arrays.asList("f1", "f2"), 0, 0);
    MockRM.Invocation call = new MockRM.Invocation("keepAlive", null, t);
    rm.keepAlive(t);
    Assert.assertEquals(call.methodName, call, mockImpl.lastCall);

    t = new Transaction("t2", Arrays.asList("f21", "f22"), 0, 0);
    call = new MockRM.Invocation("beginWriteTransaction", null, t.getTableName(),  t.getColumnFamilies());
    call.ret = rm.beginWriteTransaction(t.getTableName(), t.getColumnFamilies());
    Assert.assertEquals(call.methodName, call, mockImpl.lastCall);

    call = new MockRM.Invocation("createSnapshot", null, "t3", 1L);
    call.ret = rm.createSnapshot("t3", 1);
    Assert.assertEquals(call.methodName, call, mockImpl.lastCall);

  }

}
