/*
 * 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.nutch.fetcher;

import java.lang.invoke.MethodHandles;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.HashSet;
import java.util.Set;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class handles FetchItems which come from the same host ID (be it a
 * proto/hostname or proto/IP pair). It also keeps track of requests in
 * progress and elapsed time between requests.
 */
public class FetchItemQueue {

  private static final Logger LOG = LoggerFactory
      .getLogger(MethodHandles.lookup().lookupClass());

  List<FetchItem> queue = Collections
      .synchronizedList(new LinkedList<FetchItem>());
  AtomicInteger inProgress = new AtomicInteger();
  AtomicLong nextFetchTime = new AtomicLong();
  AtomicInteger exceptionCounter = new AtomicInteger();
  long crawlDelay;
  long minCrawlDelay;
  int maxThreads;
  Text cookie;
  Text variableFetchDelayKey = new Text("_variableFetchDelay_");
  boolean variableFetchDelaySet = false;
  // keep track of duplicates if fetcher.follow.outlinks.depth > 0. Some urls may 
  // not get followed due to hash collisions. Hashing is used to reduce memory
  // usage.
  Set<Integer> alreadyFetched = new HashSet<>();
  
  public FetchItemQueue(Configuration conf, int maxThreads, long crawlDelay,
      long minCrawlDelay) {
    this.maxThreads = maxThreads;
    this.crawlDelay = crawlDelay;
    this.minCrawlDelay = minCrawlDelay;
    // ready to start
    setEndTime(System.currentTimeMillis() - crawlDelay);
  }

  public synchronized int emptyQueue() {
    int presize = queue.size();
    queue.clear();
    return presize;
  }

  public int getQueueSize() {
    return queue.size();
  }

  public int getInProgressSize() {
    return inProgress.get();
  }

  public int incrementExceptionCounter() {
    return exceptionCounter.incrementAndGet();
  }

  public void finishFetchItem(FetchItem it, boolean asap) {
    if (it != null) {
      inProgress.decrementAndGet();
      setEndTime(System.currentTimeMillis(), asap);
    }
  }

  public void addFetchItem(FetchItem it) {
    if (it == null)
      return;

    // Check for variable crawl delay
    if (it.datum.getMetaData().containsKey(variableFetchDelayKey)) {
      if (!variableFetchDelaySet) {
        variableFetchDelaySet = true;
        crawlDelay = ((LongWritable)(it.datum.getMetaData().get(variableFetchDelayKey))).get();
        minCrawlDelay = ((LongWritable)(it.datum.getMetaData().get(variableFetchDelayKey))).get();
        setEndTime(System.currentTimeMillis() - crawlDelay);
      }
      
      // Remove it!
      it.datum.getMetaData().remove(variableFetchDelayKey);
    }
    queue.add(it);
  }

  public void addInProgressFetchItem(FetchItem it) {
    if (it == null)
      return;
    inProgress.incrementAndGet();
  }

  public FetchItem getFetchItem() {
    if (inProgress.get() >= maxThreads)
      return null;
    long now = System.currentTimeMillis();
    if (nextFetchTime.get() > now)
      return null;
    FetchItem it = null;
    if (queue.size() == 0)
      return null;
    try {
      it = queue.remove(0);
      inProgress.incrementAndGet();
    } catch (Exception e) {
      LOG.error(
          "Cannot remove FetchItem from queue or cannot add it to inProgress queue",
          e);
    }
    return it;
  }
  
  public void setCookie(Text cookie) {
    this.cookie = cookie;
  }
  
  public Text getCookie() {
    return cookie;
  }

  public synchronized void dump() {
    LOG.info("  maxThreads    = " + maxThreads);
    LOG.info("  inProgress    = " + inProgress.get());
    LOG.info("  crawlDelay    = " + crawlDelay);
    LOG.info("  minCrawlDelay = " + minCrawlDelay);
    LOG.info("  nextFetchTime = " + nextFetchTime.get());
    LOG.info("  now           = " + System.currentTimeMillis());
    for (int i = 0; i < queue.size(); i++) {
      FetchItem it = queue.get(i);
      LOG.info("  " + i + ". " + it.url);
    }
  }

  private void setEndTime(long endTime) {
    setEndTime(endTime, false);
  }

  private void setEndTime(long endTime, boolean asap) {
    if (!asap)
      nextFetchTime.set(endTime
          + (maxThreads > 1 ? minCrawlDelay : crawlDelay));
    else
      nextFetchTime.set(endTime);
  }
}
