/*
 * 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.carbondata.core.indexstore;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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;
import java.util.concurrent.TimeUnit;

import org.apache.carbondata.common.logging.LogServiceFactory;
import org.apache.carbondata.core.util.CarbonProperties;
import org.apache.carbondata.core.util.CarbonThreadFactory;

import org.apache.hadoop.io.Writable;
import org.apache.log4j.Logger;

/**
 * below class will be used to send split information from index driver to
 * main driver.
 * Main driver will Deserialize the extended blocklet object and get the split
 * to run the query
 */
public class ExtendedBlockletWrapperContainer implements Writable {

  private static final Logger LOGGER =
      LogServiceFactory.getLogService(ExtendedBlockletWrapperContainer.class.getName());

  private ExtendedBlockletWrapper[] extendedBlockletWrappers;

  private boolean isFallbackJob;

  public ExtendedBlockletWrapperContainer() {

  }

  public ExtendedBlockletWrapperContainer(ExtendedBlockletWrapper[] extendedBlockletWrappers,
      boolean isFallbackJob) {
    this.extendedBlockletWrappers = extendedBlockletWrappers;
    this.isFallbackJob = isFallbackJob;
  }

  public List<ExtendedBlocklet> getExtendedBlockets(String tablePath, String queryId,
      boolean isCountJob) throws IOException {
    if (!isFallbackJob) {
      int numOfThreads = CarbonProperties.getNumOfThreadsForPruning();
      ExecutorService executorService = Executors
          .newFixedThreadPool(numOfThreads, new CarbonThreadFactory("SplitDeseralizerPool", true));
      int numberOfWrapperPerThread = extendedBlockletWrappers.length / numOfThreads;
      int leftOver = extendedBlockletWrappers.length % numOfThreads;
      int[] split = null;
      if (numberOfWrapperPerThread > 0) {
        split = new int[numOfThreads];
      } else {
        split = new int[leftOver];
      }
      Arrays.fill(split, numberOfWrapperPerThread);
      for (int i = 0; i < leftOver; i++) {
        split[i] += 1;
      }
      int start = 0;
      int end = 0;
      List<Future<List<ExtendedBlocklet>>> futures = new ArrayList<>();
      for (int i = 0; i < split.length; i++) {
        end += split[i];
        futures.add(executorService.submit(
            new ExtendedBlockletDeserializerThread(start, end, tablePath, queryId, isCountJob)));
        start += split[i];
      }
      executorService.shutdown();
      try {
        executorService.awaitTermination(1, TimeUnit.HOURS);
      } catch (InterruptedException e) {
        LOGGER.error(e);
        throw new RuntimeException(e);
      }
      List<ExtendedBlocklet> extendedBlocklets = new ArrayList<>();
      for (int i = 0; i < futures.size(); i++) {
        try {
          extendedBlocklets.addAll(futures.get(i).get());
        } catch (InterruptedException | ExecutionException e) {
          LOGGER.error(e);
          throw new RuntimeException(e);
        }
      }
      return extendedBlocklets;
    } else {
      List<ExtendedBlocklet> extendedBlocklets = new ArrayList<>();
      for (ExtendedBlockletWrapper extendedBlockletWrapper: extendedBlockletWrappers) {
        extendedBlocklets
            .addAll(extendedBlockletWrapper.readBlocklet(tablePath, queryId, isCountJob));
      }
      return extendedBlocklets;
    }
  }

  private class ExtendedBlockletDeserializerThread implements Callable<List<ExtendedBlocklet>> {

    private int start;

    private int end;

    private String tablePath;

    private String queryId;

    private boolean isCountJob;

    public ExtendedBlockletDeserializerThread(int start, int end, String tablePath,
        String queryId, boolean isCountJob) {
      this.start = start;
      this.end = end;
      this.tablePath = tablePath;
      this.queryId = queryId;
      this.isCountJob = isCountJob;
    }

    @Override
    public List<ExtendedBlocklet> call() throws Exception {
      List<ExtendedBlocklet> extendedBlocklets = new ArrayList<>();
      for (int i = start; i < end; i++) {
        extendedBlocklets.addAll(extendedBlockletWrappers[i].readBlocklet(tablePath, queryId,
            isCountJob));
      }
      return extendedBlocklets;
    }
  }

  @Override
  public void write(DataOutput out) throws IOException {
    out.writeInt(extendedBlockletWrappers.length);
    for (int i = 0; i < extendedBlockletWrappers.length; i++) {
      extendedBlockletWrappers[i].write(out);
    }
  }

  @Override
  public void readFields(DataInput in) throws IOException {
    extendedBlockletWrappers = new ExtendedBlockletWrapper[in.readInt()];
    for (int i = 0; i < extendedBlockletWrappers.length; i++) {
      ExtendedBlockletWrapper extendedBlockletWrapper = new ExtendedBlockletWrapper();
      extendedBlockletWrapper.readFields(in);
      extendedBlockletWrappers[i] = extendedBlockletWrapper;
    }
  }
}
