package aQute.lib.osgi;

import java.util.*;
import java.util.regex.*;

import aQute.libg.generics.*;

public class Instruction {
    Pattern pattern;
    String  instruction;
    boolean negated;
    boolean optional;

    public Instruction(String instruction, boolean negated) {
        this.instruction = instruction;
        this.negated = negated;
    }

    public boolean matches(String value) {
        return getMatcher(value).matches();
    }

    public boolean isNegated() {
        return negated;
    }

    public String getPattern() {
        return instruction;
    }

    /**
     * Convert a string based pattern to a regular expression based pattern.
     * This is called an instruction, this object makes it easier to handle the
     * different cases
     * 
     * @param string
     * @return
     */
    public static Instruction getPattern(String string) {
        boolean negated = false;
        if (string.startsWith("!")) {
            negated = true;
            string = string.substring(1);
        }
        StringBuffer sb = new StringBuffer();
        for (int c = 0; c < string.length(); c++) {
            switch (string.charAt(c)) {
            case '.':
                sb.append("\\.");
                break;
            case '*':
                sb.append(".*");
                break;
            case '?':
                sb.append(".?");
                break;
            default:
                sb.append(string.charAt(c));
                break;
            }
        }
        string = sb.toString();
        if (string.endsWith("\\..*")) {
            sb.append("|");
            sb.append(string.substring(0, string.length() - 4));
        }
        return new Instruction(sb.toString(), negated);
    }

    public String toString() {
        return getPattern();
    }

    public Matcher getMatcher(String value) {
        if (pattern == null) {
            pattern = Pattern.compile(instruction);
        }
        return pattern.matcher(value);
    }

    public int hashCode() {
        return instruction.hashCode();
    }

    public boolean equals(Object other) {
        return other != null && (other instanceof Instruction)
                && instruction.equals(((Instruction) other).instruction);
    }

    public void setOptional() {
        optional = true;
    }

    public boolean isOptional() {
        return optional;
    }

    public static Map<Instruction, Map<String, String>> replaceWithInstruction(
            Map<String, Map<String, String>> header) {
        Map<Instruction, Map<String, String>> map = Processor.newMap();
        for (Iterator<Map.Entry<String, Map<String, String>>> e = header
                .entrySet().iterator(); e.hasNext();) {
            Map.Entry<String, Map<String, String>> entry = e.next();
            String pattern = entry.getKey();
            Instruction instr = getPattern(pattern);
            String presence = entry.getValue()
                    .get(Constants.PRESENCE_DIRECTIVE);
            if ("optional".equals(presence))
                instr.setOptional();
            map.put(instr, entry.getValue());
        }
        return map;
    }

    public static <T> Collection<T> select(Collection<Instruction> matchers,
            Collection<T> targets) {
        Collection<T> result = Create.list();
        outer: for (T t : targets) {
            String s = t.toString();
            for (Instruction i : matchers) {
                if (i.matches(s)) {
                    if (!i.isNegated())
                        result.add(t);
                    continue outer;
                }
            }
        }
        return result;
    }
}
