package de.visone.crawl;

import java.util.LinkedList;
import java.util.List;

import de.visone.crawl.accept.LinkAccepter;
import de.visone.crawl.rules.HtmlQuery;
import de.visone.crawl.rules.RuleManager;

/**
 * This class holds the settings to configure the crawler.
 * 
 * @see Crawler
 * 
 * @author Joschi
 * 
 */
public class Settings {
    /**
     * The user agent for the HTTP connection. If null, the Java VM decides.
     */
    public String userAgent;

    /**
     * The mean delay between two network requests in milliseconds. The actual
     * time is chosen randomly. The default value is <code>1000</code> or 1
     * second.
     */
    public long meanDelay = 1000;

    /**
     * The standard HTML-Query to filter links and text. The default query takes
     * everything below the <code>&lt;body&gt;</code> node and ignores script-
     * and style-nodes.
     */
    public HtmlQuery query = new HtmlQuery("std");

    /**
     * The maximum crawling depth. Note that values larger than 4 can give huge
     * results. The default value is 2.
     */
    public int maxDepth = 2;

    /**
     * The number of pages to crawl before the crawler stops. This can be handy
     * when fine-tuning the crawler. If the value is zero, the crawling stops
     * only after the maximum depth ({@link #maxDepth}) is reached. The default
     * value is zero.
     */
    public int killLimit = 0;

    /**
     * Whether to ignore links to other domains. The default ignores other
     * domains.
     */
    public boolean onlySameHost = true;

    /**
     * When set, the attribute <code>rel=&quot;nofollow&quot;</code> in links is
     * interpreted. The default does so.
     */
    public boolean readNoFollow = true;

    /**
     * Whether to use domain specific rules / queries or just the one given by
     * {@link #query}. The default is <code>true</code>.
     * 
     * @see RuleManager
     */
    public boolean domainSpecific = true;

    /**
     * When set, the crawling process terminates after the first error occurs
     * while crawling. This can be used to prevent blacklisting the own IP from
     * the crawled domain, when the crawler is configured to eager. This option
     * can make the use of the crawler very safe, but it can be annoying when
     * other / similar errors occur without being blacklisted. The default
     * behavior is to never stop crawling because of errors.
     * 
     * @see #coolDown
     */
    public boolean haltOnError = false;

    /**
     * EXPERIMENTAL! Accepts cookies from the first URL.
     */
    // TODO: on demand
    public boolean acceptCookies = false;

    /**
     * Returns the crawled text as XML. The default is <code>false</code>.
     */
    public boolean xmlText = false;

    /**
     * Whether to crawl text. The default crawls text.
     */
    public boolean doText = true;

    /**
     * Whether to crawl links. The default crawls links.
     */
    public boolean doLinks = true;

    /**
     * EXPERIMENTAL! Crawls in otherwise authority restricted areas. The default
     * does nothing.
     * 
     * @see #authorizationPassword
     */
    // TODO: on demand
    public String authorizationName = null;

    /**
     * EXPERIMENTAL! The password for the authorization.
     * 
     * @see #authorizationName
     */
    // TODO: on demand
    public String authorizationPassword = null;

    /**
     * The time needed to recover from an error in milliseconds. When an error
     * occurs the program will halt for this amount of time and then continue
     * again. This option is only in effect, when {@link #haltOnError} is not
     * active.
     * 
     * @see #haltOnError
     */
    public int coolDown = 5000;

    /**
     * A list containing additional / customized {@link LinkAccepter
     * LinkAccepters}. It is empty by default.
     */
    public final List<LinkAccepter> customAccepter = new LinkedList<LinkAccepter>();

    /**
     * Creates settings with default values.
     */
    public Settings() {
        HtmlQuery.addStd(query);
    }

}
