package com.nikhaldimann.viewselector.checker;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;

import se.fishtank.css.selectors.specifier.AttributeSpecifier;
import android.view.View;

import com.nikhaldimann.viewselector.ViewSelection;

public class AttributeSpecifierChecker implements ViewTraversalChecker {

    private final AttributeSpecifier specifier;

    public AttributeSpecifierChecker(AttributeSpecifier specifier) {
        this.specifier = specifier;
    }

    public ViewSelection check(Set<View> views) {
        ViewSelection result = new ViewSelection();
        for (View view : views) {
            String methodName = getGetterMethodName(specifier.getName());
            Object actualValue = callGetterMethod(view, methodName);

            // TODO refactor to use MatchPredicates
            if (specifier.getValue() == null) {
                if (actualValue != null) {
                    result.add(view);
                }
                continue;
            }

            if ("id".equals(specifier.getName())) {
                // TODO will need to make id a special case
            }

            // TODO more matches
        }
        return result;
    }

    // TODO extract to reuse in ViewSelectionAssert
    private static String getGetterMethodName(String attributeName) {
        return "get" + attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1);
    }

    private static Object callGetterMethod(Object object, String methodName) {
        try {
            Method method = object.getClass().getMethod(methodName);
            return method.invoke(object);
            // TODO more explicit exception messages
        } catch (SecurityException ex) {
            throw new RuntimeException(ex);
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(ex);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException(ex);
        }
    }

}

@@ -388,36 +388,37 @@
 nal 
-AttributeSpecifier specifier
+MatchPredicate matchPredicate
 ;%0A%0A 
@@ -497,157 +497,211 @@
     
-this.specifier = specifier;
+final String methodName = getGetterMethodName(specifier.getName());%0A
 %0A    
-%7D%0A%0A
     
-public ViewSelection check(Set%3CView%3E views) %7B%0A        ViewSelection result = new ViewSelection();%0A        for 
+if (specifier.getValue() == null) %7B%0A            matchPredicate = new MatchPredicate() %7B%0A                public boolean matches
 (Vie
@@ -710,16 +710,8 @@
 view
- : views
 ) %7B%0A
@@ -722,74 +722,8 @@
     
-    String methodName = getGetterMethodName(specifier.getName());%0A
     
@@ -787,17 +787,22 @@
 dName);%0A
-%0A
+      
         
@@ -809,219 +809,320 @@
     
-// TODO refactor to use MatchPredicates%0A            if (specifier.getValue() == null) %7B%0A                if (actualValue != null) %7B%0A                    result.add(view);%0A                %7D%0A                continue
+  return actualValue != null;%0A                %7D%0A            %7D;%0A        %7D else if (%22id%22.equals(specifier.getName())) %7B%0A            // TODO will need to make id a special case%0A            matchPredicate = MatchPredicates.ALWAYS_TRUE_PREDICATE;%0A        %7D else %7B%0A            throw new UnsupportedOperationException()
 ;%0A  
@@ -1119,32 +1119,34 @@
 tion();%0A        
+%7D%0A
     %7D%0A%0A         
@@ -1144,115 +1144,187 @@
     
-        if (%22id%22.equals(specifier.getName())) %7B%0A                // TODO will need to make id a special case
+public ViewSelection check(Set%3CView%3E views) %7B%0A        ViewSelection result = new ViewSelection();%0A        for (View view : views) %7B%0A            if (matchPredicate.matches(view)) %7B
 %0A   
@@ -1336,43 +1336,43 @@
     
-%7D%0A%0A
     
-        // TODO more matches
+result.add(view);%0A            %7D
 %0A   

Use MatchPredicates in attribute matching impl