/*
 * 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.geode.cache.lucene.internal.distributed;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

import org.apache.logging.log4j.Logger;

import org.apache.geode.DataSerializer;
import org.apache.geode.cache.lucene.LuceneQueryFactory;
import org.apache.geode.cache.lucene.internal.distributed.TopEntries.EntryScoreComparator;
import org.apache.geode.cache.lucene.internal.repository.IndexResultCollector;
import org.apache.geode.internal.DataSerializableFixedID;
import org.apache.geode.internal.Version;
import org.apache.geode.internal.logging.LogService;

/**
 * An implementation of {@link CollectorManager} for managing {@link TopEntriesCollector}. This is
 * used by a member to collect top matching entries from local buckets
 */
public class TopEntriesCollectorManager
    implements CollectorManager<TopEntriesCollector>, DataSerializableFixedID {
  private static final Logger logger = LogService.getLogger();

  private int limit;
  private String id;

  public TopEntriesCollectorManager() {
    this(null, 0);
  }

  public TopEntriesCollectorManager(String id) {
    this(id, 0);
  }

  public TopEntriesCollectorManager(String id, int resultLimit) {
    this.limit = resultLimit <= 0 ? LuceneQueryFactory.DEFAULT_LIMIT : resultLimit;
    this.id = id == null ? String.valueOf(this.hashCode()) : id;
    logger.debug("Max count of entries to be produced by {} is {}", id, limit);
  }

  @Override
  public TopEntriesCollector newCollector(String name) {
    return new TopEntriesCollector(name, limit);
  }

  @Override
  public TopEntriesCollector reduce(Collection<TopEntriesCollector> collectors) {
    TopEntriesCollector mergedResult = new TopEntriesCollector(id, limit);
    if (collectors.isEmpty()) {
      return mergedResult;
    }

    final EntryScoreComparator scoreComparator = new TopEntries().new EntryScoreComparator();

    // orders a entry with higher score above a doc with lower score
    Comparator<ListScanner> entryListComparator = new Comparator<ListScanner>() {
      @Override
      public int compare(ListScanner l1, ListScanner l2) {
        EntryScore o1 = l1.peek();
        EntryScore o2 = l2.peek();
        return scoreComparator.compare(o1, o2);
      }
    };

    // The queue contains iterators for all bucket results. The queue puts the entry with the
    // highest score at the head
    // using score comparator.
    PriorityQueue<ListScanner> entryListsPriorityQueue;
    entryListsPriorityQueue = new PriorityQueue<ListScanner>(collectors.size(),
        Collections.reverseOrder(entryListComparator));

    for (IndexResultCollector collector : collectors) {
      logger.debug("Number of entries found in collector {} is {}", collector.getName(),
          collector.size());

      if (collector.size() > 0) {
        entryListsPriorityQueue
            .add(new ListScanner(((TopEntriesCollector) collector).getEntries().getHits()));
      }
    }

    logger.debug("Only {} count of entries will be reduced. Other entries will be ignored", limit);
    while (entryListsPriorityQueue.size() > 0 && limit > mergedResult.size()) {

      ListScanner scanner = entryListsPriorityQueue.remove();
      EntryScore entry = scanner.next();
      mergedResult.collect(entry);

      if (scanner.hasNext()) {
        entryListsPriorityQueue.add(scanner);
      }
    }

    logger.debug("Reduced size of {} is {}", mergedResult.getName(), mergedResult.size());
    return mergedResult;
  }

  /*
   * Utility class to iterate on hits without modifying it
   */
  static class ListScanner {
    private List<EntryScore> hits;
    private int index = 0;

    ListScanner(List<EntryScore> hits) {
      this.hits = hits;
    }

    boolean hasNext() {
      return index < hits.size();
    }

    EntryScore peek() {
      return hits.get(index);
    }

    EntryScore next() {
      return hits.get(index++);
    }
  }

  @Override
  public Version[] getSerializationVersions() {
    return null;
  }

  @Override
  public int getDSFID() {
    return LUCENE_TOP_ENTRIES_COLLECTOR_MANAGER;
  }

  @Override
  public void toData(DataOutput out) throws IOException {
    DataSerializer.writeString(id, out);
    out.writeInt(limit);
  }

  @Override
  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
    id = DataSerializer.readString(in);
    limit = in.readInt();
  }

  /**
   * @return Id of this collector, if any
   */
  public String getId() {
    return id;
  }

  /**
   * @return Result limit enforced by the collectors created by this manager
   */
  public int getLimit() {
    return limit;
  }
}
