package nsxl.rotpales;

import org.apache.commons.beanutils.ConvertUtils;

import java.io.Reader;
import java.io.BufferedReader;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.MatchResult;

/**
 * Created by IntelliJ IDEA.
 * User: garyt_2
 * Date: 21-May-2004
 * Time: 20:31:50
 * To change this template use File | Settings | File Templates.
 */
public class LineParser {
    private Formatter form;
    private List<Handler> handlers =  new ArrayList<Handler>();
    static final String EMPTY_STRING = "";
    interface Handler {
        public Matcher getMatcher();
        public Class getObjectType(int i);
        public void foundMatch(Object... matches);
        public boolean matches(String target);
    }

    abstract static  class AbstractHandler implements Handler {
        Matcher matcher;
        List<Class> types;
        public AbstractHandler(Pattern pattern, Class ... types) {
              this.matcher = pattern.matcher(EMPTY_STRING);
              if(matcher.groupCount() != types.length) {
                  String msg = "number of capture groups in expression must equal types!";
                  throw new IllegalArgumentException(msg);
              }

            this.types= Arrays.asList(types);
        }

        public boolean matches(String target) {
            matcher.reset(target);
            return matcher.matches();
        }

        public Matcher getMatcher() {
            return matcher;
        }

        public Class getObjectType(int i) {
            return null;
        }

        abstract public void foundMatch(Object... matches);



    }
    void parse(BufferedReader input) {
        BufferedReader lineReader =  new BufferedReader(input);
        Scanner scanner  =  Scanner.create(lineReader);
        scanner.useDelimiter("\n");

        for(String line:  Scannable.create(scanner)) {
            for(Handler handler: handlers) {
                if(handler.matches(line)) {
                    buildAndFireMatch(handler);
                }
            }
        }

    }

    private void buildAndFireMatch(Handler handler) {
         MatchResult matchResult = handler.getMatcher().asResult();
         int matchCount = matchResult.groupCount();
         Object[] results = new Object[matchCount];

         for(int i = 0; i< matchCount ; i++) {

            String target  = matchResult.group(i);
            Class conversionTarget = handler.getObjectType(i);
            results[i]=ConvertUtils.convert(target,conversionTarget);


         }
         handler.foundMatch(results);

    }

    public void addHandler(Handler handler) {
        handlers.add(handler);    
    }

//    void registerHandler(Handler) {
//
//    }
}
