package ch.zhaw.ads;

import java.lang.ArrayIndexOutOfBoundsException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class RankingServer implements CommandExecutor {
    List<Competitor> competitors;

    @Override
    public String execute(String input) {
        this.competitors = parseCSV(input);

        StringBuffer result = new StringBuffer(100);
        result.append("Competitors:\n");
        for (Competitor competitor : competitors) {
            result.append(competitor.toString() + "\n");
        }

        Collections.sort(competitors);
        result.append("\n\nSorted Competitors (by time):\n");
        // set the  ranks and append to output
        for (int i = 0; i < competitors.size(); i++) {
            Competitor competitor = competitors.get(i);
            competitor.setRank(i + 1);
            result.append(competitor.toString() + "\n");
        }

        Collections.sort(competitors, new Comparator<Competitor>() {
            @Override
            public int compare(Competitor o1, Competitor o2) {
                int nameCompare = o1.getName().compareTo(o2.getName());
                if (nameCompare == 0) {
                    return Integer.valueOf(o1.getJg()).compareTo(o2.getJg());
                }
                return nameCompare;
            }
        });
        result.append("\n\nSorted Competitors (by name, then birth year):\n");
        for (Competitor competitor : competitors) {
            result.append(competitor.toString() + "\n");
        }
        return result.toString();
    }

    /**
     * NOTE ABOUT CSV FORMAT (from `man virt-diff`)
     *        Comma-separated values (CSV) is a deceptive format.  It seems like it should be easy to parse,
     *        but it is definitely not easy to parse.
     *
     *        Myth: Just split fields at commas.  Reality: This does not work reliably.  This example has two
     *        columns:
     *
     *         "foo,bar",baz
     *
     *        Myth: Read the file one line at a time.  Reality: This does not work reliably.  This example has
     *        one row:
     *
     *         "foo
     *         bar",baz
     */
    private List<Competitor> parseCSV(String csv) {
        int startNr, jg;
        String name, country, time;

        List<Competitor> competitors = new ArrayList<Competitor>();
        for (String record : csv.split("\\r?\\n")) {
            String[] values = record.split(";");

            try {
                startNr = Integer.valueOf(values[0]);
                name = values[1];
                jg = Integer.valueOf(values[2]);
                country = values[3];
                time = values[4];
                competitors.add(new Competitor(startNr, name, jg, country, time));
            } catch (NumberFormatException | ParseException | ArrayIndexOutOfBoundsException e) {
                System.err.println("Failed to add competitor.");
                continue;
            }
        }
        return competitors;
    }
}
