import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Scanner;

public class Poète {
	private static class Préfixe {
		public String avantDernier, dernier;

		public Préfixe(String avantDernier, String dernier) {
			this.avantDernier = avantDernier;
			this.dernier = dernier;
		}

		public Préfixe(Préfixe p) {
			this(p.avantDernier, p.dernier);
		}

		public int hashCode() {
			return avantDernier.hashCode() + dernier.hashCode();
		}

		public boolean equals(Object obj) {
			if (obj == null || obj.getClass() != this.getClass())
				return false;
			if (obj == this)
				return true;
			Préfixe p = (Préfixe) obj;
			return p.avantDernier.equals(avantDernier)
					&& p.dernier.equals(dernier);
		}
	}

	private ArrayList<Préfixe> débuts;
	private HashMap<Préfixe, ArrayList<String>> savoir;

	public Poète() {
		débuts = new ArrayList<Préfixe>();
		savoir = new HashMap<Préfixe, ArrayList<String>>();
	}

	public boolean neSaitRien() {
		return savoir.isEmpty();
	}

	public void printStatistiques() {
		int nbDébuts = débuts.size();
		int nbPréfixes = savoir.size();
		int max = 0, nbSup = 0, cumul = 0;
		for (ArrayList<String> mots : savoir.values()) {
			int nb = mots.size();
			if (nb > max)
				max = nb;
			if (nb > 1)
				++nbSup;
			cumul += nb;
		}
		System.out.println("nbre de textes : " + nbDébuts);
		System.out.println("nbre de préfixes : " + nbPréfixes);
		System.out.println("nbre maximal de mots liés à un même préfixe : "
				+ max);
		System.out
				.println("nbre de préfixes associés à au - 2 mots : " + nbSup);
		if (nbPréfixes != 0)
			System.out.println("nbre moyen de mots associés aux préfixes : "
					+ ((float) cumul / nbPréfixes));
	}

	public void apprendre(String nom) throws FileNotFoundException,
			NoSuchElementException {
		Scanner sc = new Scanner(new File(nom));
		// si le fichier contient moins de 2 mots, les deux lectures
		// suivantes lèvent l'exception NoSuchElementException
		Préfixe p = new Préfixe(sc.next(), sc.next());
		débuts.add(new Préfixe(p));
		while (sc.hasNext()) {
			String s = sc.next();
			ajouterMotAPréfixe(p, s);
			p.avantDernier = p.dernier;
			p.dernier = s;
		}
		ajouterMotAPréfixe(p, "");
		sc.close();
	}

	private void ajouterMotAPréfixe(Préfixe p, String s) {
		if (savoir.containsKey(p))
			savoir.get(p).add(s);
		else
			savoir.put(new Préfixe(p), new ArrayList<String>(Arrays.asList(s)));
	}

	public String inventer() {
		assert (!neSaitRien());
		StringBuilder sb = new StringBuilder();
		Random rd = new Random();
		Préfixe p = new Préfixe(débuts.get(rd.nextInt(débuts.size())));
		sb.append(p.avantDernier + " " + p.dernier);
		while (savoir.containsKey(p)) {
			ArrayList<String> mots = savoir.get(p);
			String s = mots.get(rd.nextInt(mots.size()));
			sb.append(" " + s);
			p.avantDernier = p.dernier;
			p.dernier = s;
		}
		return sb.toString();
	}
}
