/*
 * Yet Another UserAgent Analyzer
 * Copyright (C) 2013-2017 Niels Basjes
 *
 * 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 nl.basjes.parse.useragent.dissector;

import nl.basjes.parse.core.Dissector;
import nl.basjes.parse.core.Field;
import nl.basjes.parse.core.Parser;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.assertEquals;

public class TestDissectUserAgent {
    public class TestRecordUserAgent {

        private final Map<String, String> results = new HashMap<>(32);

        @SuppressWarnings({"unused"}) // Used via reflection
        @Field({
            "STRING:device_class",
            "STRING:device_name",
            "STRING:device_cpu",

            "STRING:operating_system_class",
            "STRING:operating_system_name",
            "STRING:operating_system_version",

            "STRING:layout_engine_class",
            "STRING:layout_engine_name",
            "STRING:layout_engine_version",

            "STRING:agent_class",
            "STRING:agent_name",
            "STRING:agent_version",
        })
        public void setValue(final String name, final String value) {
            results.put(name, value);
        }
    }

    class UAParser extends Parser<TestRecordUserAgent> {
        public UAParser() {
            super(TestRecordUserAgent.class);
            Dissector userAgentDissector = new UserAgentDissector();
            addDissector(userAgentDissector);
            setRootType(userAgentDissector.getInputType());
        }
    }

    @Test
    public void testUserAgentDissector() throws Exception {
        UAParser uaParser = new UAParser();
        TestRecordUserAgent record = new TestRecordUserAgent();
        uaParser.parse(record, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36");

        Map<String, String> results = record.results;

        assertEquals("Desktop",       results.get("STRING:device_class"));
        assertEquals("Linux Desktop", results.get("STRING:device_name"));
        assertEquals("Intel x86_64",  results.get("STRING:device_cpu"));

        assertEquals("Desktop",       results.get("STRING:operating_system_class"));
        assertEquals("Linux",         results.get("STRING:operating_system_name"));
        assertEquals("Intel x86_64",  results.get("STRING:operating_system_version"));

        assertEquals("Browser",       results.get("STRING:layout_engine_class"));
        assertEquals("Blink",         results.get("STRING:layout_engine_name"));
        assertEquals("48.0",          results.get("STRING:layout_engine_version"));

        assertEquals("Browser",       results.get("STRING:agent_class"));
        assertEquals("Chrome",        results.get("STRING:agent_name"));
        assertEquals("48.0.2564.82",  results.get("STRING:agent_version"));
    }

    @Test
    public void validateNameConversion() {
        assertEquals("foo",         UserAgentDissector.fieldNameToDissectionName("Foo"));
        assertEquals("foo_bar",     UserAgentDissector.fieldNameToDissectionName("FooBar"));
        assertEquals("foo_bar_baz", UserAgentDissector.fieldNameToDissectionName("FooBarBaz"));
    }


}

@@ -809,16 +809,106 @@
 .Test;%0A%0A
+import java.lang.reflect.Constructor;%0Aimport java.lang.reflect.InvocationTargetException;%0A
 import j
@@ -1909,16 +1909,144 @@
 Parser()
+ throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException
  %7B%0A     
@@ -2086,16 +2086,17 @@
 class);%0A
+%0A
         
@@ -2098,16 +2098,45 @@
         
+ // We do this%0A            //
  Dissect
@@ -2181,24 +2181,605 @@
 issector();%0A
+            // Via reflection to test that instantiation route%0A            String dissectorClassName = UserAgentDissector.class.getCanonicalName();%0A            Class%3C?%3E clazz = Class.forName(dissectorClassName);%0A            Constructor%3C?%3E constructor = clazz.getConstructor();%0A            Dissector userAgentDissector = (Dissector) constructor.newInstance();%0A            if (!userAgentDissector.initializeFromSettingsParameter(null)) %7B%0A                throw new IllegalArgumentException(%22Initialization failed of dissector instance of class %22 + dissectorClassName);%0A            %7D%0A%0A
             

Test dissector instantiation via reflection