package jp.sourceforge.shovel.mobilephone.impl;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import jp.sourceforge.shovel.exception.ApplicationException;
import jp.sourceforge.shovel.mobilephone.ISoftBank;
import junit.framework.Assert;

import org.junit.runner.RunWith;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import org.seasar.framework.mock.servlet.MockHttpServletRequest;
import org.seasar.framework.unit.Seasar2;
import org.seasar.framework.unit.TestContext;
import org.seasar.framework.util.ResourceUtil;

import au.com.bytecode.opencsv.CSVReader;

@RunWith(Seasar2.class)
public class SoftBankImplTest {
    TestContext context_;
    Map<String, Map<String, String>> profiles_;
    HttpServletRequest request_;
    
    public SoftBankImplTest() throws IOException {
        profiles_ = new HashMap<String, Map<String, String>>();
        File file = ResourceUtil.getResourceAsFile("jp.sourceforge.shovel.mobilephone.impl.SoftBankImplTest", "csv");
        CSVReader reader = new CSVReader(new FileReader(file));
        String[] keys = reader.readNext();
        String[] line;
        while ((line = reader.readNext()) != null) {
            HashMap<String, String> profile = new HashMap<String, String>();
            //0はUserAgent
            for (int i = 1; i < keys.length; i++) {
                String value = line[i];
                if (value.length() <= 0) {
                    value = null;
                }
                profile.put(keys[i], value);
            }
            profiles_.put(line[0], profile);
        }
        reader.close();
    }
    
    public void testShouldDetectUserAgentsAsSoftbank() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
            softbank.parse(userAgent);
            
            Assert.assertFalse(softbank.isDoCoMo());
            Assert.assertFalse(softbank.isEZweb());
            Assert.assertTrue(softbank.isSoftBank());
            Assert.assertFalse(softbank.isEmobile());
            Assert.assertFalse(softbank.isWillcom());
            Assert.assertFalse(softbank.isNotMobile());
        }
    }
    
    public void testShouldProvideTheModelNameOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
            softbank.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(profile.get("model"), softbank.getModel());
        }
    }
    
    public void testShouldSupportSemulator() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("Semulator/1.0/813T/TJ001/SN123456789012345 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1");
        Assert.assertTrue(softbank.isSoftBank());
        Assert.assertEquals("813T", softbank.getModel());
        Assert.assertTrue(softbank.isPacketCompliant());
        Assert.assertEquals("123456789012345", softbank.getSerialNumber());
        Assert.assertEquals("J001", softbank.getVendorVersion());
        Assert.assertEquals("MIDP-2.0", softbank.getProfile());
        Assert.assertEquals("CLDC-1.1", softbank.getConfiguration());
        Assert.assertTrue(softbank.isType3GC());
        Assert.assertEquals("Semulator", softbank.getName());
        Assert.assertEquals("1.0", softbank.getVersion());
        Assert.assertEquals("T", softbank.getVendor());
    }
    
    public void testShouldSupportVemulator() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("Vemulator/1.0/V902SH/SHJ001/SN123456789012345");
        Assert.assertTrue(softbank.isSoftBank());
        Assert.assertEquals("V902SH", softbank.getModel());
        Assert.assertTrue(softbank.isPacketCompliant());
        Assert.assertEquals("123456789012345", softbank.getSerialNumber());
        Assert.assertEquals("J001", softbank.getVendorVersion());
        Assert.assertTrue(softbank.isType3GC());
        Assert.assertEquals("Vemulator", softbank.getName());
        Assert.assertEquals("1.0", softbank.getVersion());
        Assert.assertEquals("SH", softbank.getVendor());
    }
    
    public void testShouldSupportJemulator() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("J-EMULATOR/4.3/V602SH/SN12345678901");
        Assert.assertTrue(softbank.isSoftBank());
        Assert.assertEquals("V602SH", softbank.getModel());
        Assert.assertFalse(softbank.isPacketCompliant());
        Assert.assertEquals("12345678901", softbank.getSerialNumber());
        Assert.assertTrue(softbank.isTypeP());
        Assert.assertEquals("J-EMULATOR", softbank.getName());
        Assert.assertEquals("4.3", softbank.getVersion());
        Assert.assertEquals("SH", softbank.getVendor());
    }
    
    public void testShouldProvideTheUidOfASubscriber() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("SoftBank/1.0/706SC/SCJ001 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1");
        Assert.assertNull(softbank.getUID());

        String uid = "1234567890123456";
        MockHttpServletRequest request = (MockHttpServletRequest)request_;
        request.addHeader("X-JPHONE-UID", uid);
        softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("SoftBank/1.0/706SC/SCJ001 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1");
        Assert.assertEquals(uid, softbank.getUID());
    }
    
    public void testShouldProvideTheJavaInformationOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
            softbank.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            if (profile.get("profile") == null) {
                Assert.assertNull(softbank.getProfile());
            } else {
                Assert.assertEquals(profile.get("profile"), softbank.getProfile());
            }
            if (profile.get("configuration") == null) {
                Assert.assertNull(softbank.getConfiguration());
            } else {
                Assert.assertEquals(profile.get("configuration"), softbank.getConfiguration());
            }
            if (profile.get("extJProfile") == null) {
                Assert.assertNull(softbank.getExtJProfile());
            } else {
                Assert.assertEquals(profile.get("extJProfile"), softbank.getExtJProfile());
            }
            if (profile.get("extVProfile") == null) {
                Assert.assertNull(softbank.getExtVProfile());
            } else {
                Assert.assertEquals(profile.get("extVProfile"), softbank.getExtVProfile());
            }
        }
    }
    
    public void testShouldTellWhetherAUserAgentIsAModelTypeC() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
            softbank.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Boolean.parseBoolean(profile.get("isTypeC")), softbank.isTypeC());
        }
    }
    
    public void testShouldTellWhetherAUserAgentIsAModelTypeP() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
            softbank.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Boolean.parseBoolean(profile.get("isTypeP")), softbank.isTypeP());
        }
    }

    public void testShouldTellWhetherAUserAgentIsAModelTypeW() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
            softbank.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Boolean.parseBoolean(profile.get("isTypeW")), softbank.isTypeW());
        }
    }
    
    public void testShouldTellWhetherAUserAgentIsAModelType3Gc() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
            softbank.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Boolean.parseBoolean(profile.get("isType3GC")), softbank.isType3GC());
        }
    }
    
    public void testShouldProvideTheMsnameOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("Vodafone/1.0/V702NK/NKJ001 Series60/2.6 Nokia6630/2.39.148 Profile/MIDP-2.0 Configuration/CLDC-1.1");
        Assert.assertNull(softbank.getMsname());

        String msname = "V702NK";
        MockHttpServletRequest request = (MockHttpServletRequest)request_;
        request.addHeader("X-JPHONE-MSNAME", msname);
        softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("Vodafone/1.0/V702NK/NKJ001 Series60/2.6 Nokia6630/2.39.148 Profile/MIDP-2.0 Configuration/CLDC-1.1");
        Assert.assertEquals(msname, softbank.getMsname());
    }
    
    public void testShouldProvideTheScreenInformationOfAUserAgent() throws ApplicationException {
        MockHttpServletRequest request = (MockHttpServletRequest)request_;
        request.addHeader("X-JPHONE-DISPLAY", "120*117");
        request.addHeader("X-JPHONE-COLOR", "C256");
        
        S2Container container = SingletonS2ContainerFactory.getContainer();
        ISoftBank softbank = (ISoftBank)container.getComponent(ISoftBank.class);
        softbank.parse("J-PHONE/2.0/J-DN02");
        
        Assert.assertEquals(120, softbank.getWidth());
        Assert.assertEquals(117, softbank.getHeight());
        Assert.assertTrue(softbank.isColor());
        Assert.assertEquals(256, softbank.getDepth());
    }
}
