//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   Licensed 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 de.ugoe.cs.autoquest.commands.sequences;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import de.ugoe.cs.autoquest.CommandHelpers;
import de.ugoe.cs.autoquest.SequenceInstanceOf;
import de.ugoe.cs.autoquest.eventcore.Event;
import de.ugoe.cs.util.console.Command;
import de.ugoe.cs.util.console.GlobalDataContainer;

/**
 * <p>
 * TODO comment
 * </p>
 * 
 * @author Patrick Harms
 * @version 1.0
 */
public class CMDtargetStatistics implements Command {

    /*
     * (non-Javadoc)
     * 
     * @see de.ugoe.cs.util.console.Command#run(java.util.List)
     */
    @SuppressWarnings("unchecked")
    @Override
    public void run(List<Object> parameters) {
        List<String> sequenceNames = new ArrayList<>(parameters.size());
        try {
            for (Object parameter : parameters) {
                sequenceNames.add((String) parameter);
            }
        }
        catch (Exception e) {
            throw new IllegalArgumentException();
        }

        List<Collection<List<Event>>> sequences = new ArrayList<>(sequenceNames.size());
        
        for (String sequenceName : sequenceNames) {
            Object dataObject = GlobalDataContainer.getInstance().getData(sequenceName);
            if (dataObject == null) {
                CommandHelpers.objectNotFoundMessage(sequenceName);
                return;
            }
            if (!SequenceInstanceOf.isCollectionOfSequences(dataObject)) {
                CommandHelpers.objectNotType(sequenceName, "Collection<List<Event<?>>>");
                return;
            }
            
            sequences.add((Collection<List<Event>>) dataObject);
        }
        
        Map<String, Map<String, Integer>> counters = new TreeMap<>();
        
        for (int i = 0; i < sequences.size(); i++) {
            String sequenceName = sequenceNames.get(i);
            for (List<Event> sequence : sequences.get(i)) {
                for (Event event : sequence) {
                    String targetId = event.getTarget().toString() + " (" +
                        event.getTarget().getStringIdentifier() + ")";
                    Map<String, Integer> counterMap = counters.get(targetId);
                    
                    if (counterMap == null) {
                        counterMap = new HashMap<>();
                        counters.put(targetId, counterMap);
                    }
                    
                    Integer counter = counterMap.get(sequenceName);
                    if (counter == null) {
                        counterMap.put(sequenceName, 1);
                    }
                    else {
                        counterMap.put(sequenceName, counter + 1);
                    }
                }
            }
        }
        
        int maxEventNameLength = 0;
        for (Map.Entry<String, Map<String, Integer>> sequenceStats : counters.entrySet()) {
            maxEventNameLength = Math.max(maxEventNameLength, sequenceStats.getKey().length());
        }

        List<StringBuffer> lines = new LinkedList<>();
        for (Map.Entry<String, Map<String, Integer>> sequenceStats : counters.entrySet()) {
            StringBuffer line = new StringBuffer();
            line.append(sequenceStats.getKey());
            
            for (int i = sequenceStats.getKey().length(); i < maxEventNameLength; i++) {
                line.append(' ');
            }
            
            for (String sequenceName : sequenceNames) {
                String numberStr = "";
                
                if (sequenceStats.getValue().get(sequenceName) != null) {
                    numberStr += sequenceStats.getValue().get(sequenceName);
                }
                
                line.append(" | ");
                line.append(numberStr);
                
                for (int i = numberStr.length(); i < sequenceName.length(); i++) {
                    line.append(' ');
                }
            }
            
            lines.add(line);
        }
        
        for (int i = 0; i < maxEventNameLength; i++) {
            System.out.print(' ');
        }
        
        for (String sequenceName : sequenceNames) {
            System.out.print(" | " + sequenceName);
        }
        
        System.out.println();
        
        for (StringBuffer line : lines) {
            System.out.println(line);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see de.ugoe.cs.util.console.Command#help()
     */
    @Override
    public String help() {
        return "eventStatistics [<sequencesName>]*";
    }

}
