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.dao.IDoCoMoExtendDao;
import jp.sourceforge.shovel.exception.ApplicationException;
import jp.sourceforge.shovel.mobilephone.IDoCoMo;
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 DoCoMoImplTest {
    TestContext context_;
    Map<String, Map<String, String>> profiles_;
    HttpServletRequest request_;
    IDoCoMoExtendDao dao_;
    
    public DoCoMoImplTest() throws IOException {
        profiles_ = new HashMap<String, Map<String, String>>();
        File file = ResourceUtil.getResourceAsFile("jp.sourceforge.shovel.mobilephone.impl.DoCoMoImplTest", "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 = null;
                if (line.length > i) {
                    value = line[i];
                }
                profile.put(keys[i], value);
            }
            profiles_.put(line[0], profile);
        }
        reader.close();
    }
    
    public void testShouldDetectUserAgentsAsDocomo() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Assert.assertTrue(docomo.isDoCoMo());
            Assert.assertFalse(docomo.isEZweb());
            Assert.assertFalse(docomo.isSoftBank());
            Assert.assertFalse(docomo.isEmobile());
            Assert.assertFalse(docomo.isWillcom());
            Assert.assertFalse(docomo.isNotMobile());
        }
    }
    
    public void testShouldProvideTheModelNameOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(profile.get("model"), docomo.getModel());
        }
    }
    
    public void testShouldProvideTheHTMLVersionOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(profile.get("htmlVersion"), docomo.getHTMLVersion());
        }
    }
    
    public void testShouldProvideTheScreenAreaOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Integer.parseInt(profile.get("width")), docomo.getWidth());
            Assert.assertEquals(Integer.parseInt(profile.get("height")), docomo.getHeight());
        }
    }
    public void testShouldSupprtYahooWebCrawler() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
        docomo.parse("DoCoMo/2.0 SH902i (compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html)");
        
        Assert.assertTrue(docomo.isDoCoMo());
        Assert.assertEquals("SH902i", docomo.getModel());
        Assert.assertNull(docomo.getStatus());
        Assert.assertEquals(0, docomo.getBandWidth());
        Assert.assertNull(docomo.getSerialNumber());
        Assert.assertTrue(docomo.isFOMA());
        Assert.assertNull(docomo.getCardID());
        Assert.assertEquals("compatible; Y!J-SRD/1.0; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-27.html", docomo.getComment());
        Assert.assertEquals(5, docomo.getCacheSize());
        Assert.assertEquals("DoCoMo", docomo.getName());
        Assert.assertEquals("2.0", docomo.getVersion());
    }
    
    public void testShouldSupprtDenaWebCrawler() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
        docomo.parse("DoCoMo/2.0 N902iS(c100;TB;W24H12)(compatible; moba-crawler; http://crawler.dena.jp/)");
        
        Assert.assertTrue(docomo.isDoCoMo());
        Assert.assertEquals("N902iS", docomo.getModel());
        Assert.assertEquals("TB", docomo.getStatus());
        Assert.assertEquals(0, docomo.getBandWidth());
        Assert.assertNull(docomo.getSerialNumber());
        Assert.assertTrue(docomo.isFOMA());
        Assert.assertNull(docomo.getCardID());
        Assert.assertEquals("compatible; moba-crawler; http://crawler.dena.jp/", docomo.getComment());
        Assert.assertEquals(100, docomo.getCacheSize());
        Assert.assertEquals("DoCoMo", docomo.getName());
        Assert.assertEquals("2.0", docomo.getVersion());
    }
    public void testShouldProvideTheUidOfASubscriber() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
        docomo.parse("DoCoMo/2.0 SH905i(c100;TB;W24H16)");
        Assert.assertNull(docomo.getUID());

        String uid = "1234567";
        MockHttpServletRequest request = (MockHttpServletRequest)request_;
        request.addHeader("X-DCMGUID", uid);
        docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
        docomo.parse("DoCoMo/2.0 SH905i(c100;TB;W24H16)");
        Assert.assertEquals(uid, docomo.getUID());
    }
    
    public void testShouldProvideTheVersionOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(profile.get("version"), docomo.getVersion());
        }
    }
    
    public void testShouldProvideTheCacheSizeOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Integer.parseInt(profile.get("cacheSize")), docomo.getCacheSize());
        }
    }
    
    public void testShouldTellWhetherAUserAgentIsFomaOrNot() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Boolean.parseBoolean(profile.get("isFOMA")), docomo.isFOMA());
        }
    }
    
    public void testShouldProvideTheVendorOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(profile.get("vendor"), docomo.getVendor());
        }
    }
    
    public void testShouldProvideTheSeriesOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(profile.get("series"), docomo.getSeries());
        }
    }
    
    public void testShouldProvideTheStatusOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            if (profile.get("status").length() > 0) {
                Assert.assertEquals(profile.get("status"), docomo.getStatus());
            } else {
                Assert.assertNull(docomo.getStatus());
            }
        }
    }
    
    public void testShouldProvideTheSerialNumberOfAsUserAgent() throws ApplicationException {
        Map<String, String> serialNumbers = new HashMap<String, String>();
        serialNumbers.put("DoCoMo/1.0/P503i/c10/serNMABH200331", "NMABH200331");
        serialNumbers.put("DoCoMo/2.0 N2001(c10;ser0123456789abcde;icc01234567890123456789)", "0123456789abcde");
        serialNumbers.put("DoCoMo/2.0 NM850iG(c100;TB;W22H10;ser123456789012345;icc)", "123456789012345");
        
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : serialNumbers.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            Assert.assertEquals(serialNumbers.get(userAgent), docomo.getSerialNumber());
        }
    }
    
    public void testShouldProvideTheCardIDOfAsUserAgent() throws ApplicationException {
        Map<String, String> cardIDs = new HashMap<String, String>();
        cardIDs.put("DoCoMo/2.0 N2001(c10;ser0123456789abcde;icc01234567890123456789)", "01234567890123456789");

        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : cardIDs.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            Assert.assertEquals(cardIDs.get(userAgent), docomo.getCardID());
        }
    }
    
    public void testShouldProvideTheBandWidthOfAsUserAgent() throws ApplicationException {
        Map<String, Integer> bandWidths = new HashMap<String, Integer>();
        bandWidths.put("DoCoMo/1.0/eggy/c300/s32/kPHS-K", 32);
        bandWidths.put("DoCoMo/1.0/P751v/c100/s64/kPHS-K", 64);
        
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : bandWidths.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            Assert.assertEquals(bandWidths.get(userAgent).intValue(), docomo.getBandWidth());
        }
    }
    
    public void testShouldTellWhetherAUserAgentIsAGpsModelOrNot() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        for (String userAgent : profiles_.keySet()) {
            IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
            docomo.parse(userAgent);
            
            Map<String, String> profile = profiles_.get(userAgent);
            Assert.assertEquals(Boolean.parseBoolean(profile.get("isGPS")), docomo.isGPS());
        }
    }
    
    public void testShouldProvideTheScreenInformationOfAUserAgent() throws ApplicationException {
        S2Container container = SingletonS2ContainerFactory.getContainer();
        IDoCoMo docomo = (IDoCoMo)container.getComponent(IDoCoMo.class);
        docomo.parse("DoCoMo/2.0 P705iCL(c100;TB;W16H10)");
        
        Assert.assertEquals(240, docomo.getWidth());
        Assert.assertEquals(350, docomo.getHeight());
        Assert.assertEquals(262144, docomo.getDepth());
        Assert.assertTrue(docomo.isColor());
        Assert.assertEquals(16, docomo.getWidthBytes());
        Assert.assertEquals(10, docomo.getHeightBytes());
    }
}
