package tryslim3.service;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.slim3.datastore.Datastore;
import org.slim3.tester.AppEngineTestCase;
import org.slim3.util.DateUtil;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.Transaction;

import tryslim3.meta.Crud2Meta;
import tryslim3.model.Crud2;
import tryslim3.model.Crud2Form;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

public class Crud2ServiceTest extends AppEngineTestCase {

    private Crud2Service service = new Crud2Service();

    private static final int MAX_DATA = 10;

    @Before
    public void setUp() throws Exception {
        super.setUp();

        // DBクリア
        Transaction tx = Datastore.beginTransaction();
        clearData(tx);
        Datastore.commit(tx);

        // データ登録
        for (int i = 0; i < MAX_DATA; i++) {
            tx = Datastore.beginTransaction();
            Datastore.put(tx, createData(i));
            Datastore.commit(tx);
        }
    }

    private void clearData(Transaction tx) {
        Crud2Meta meta = new Crud2Meta();
        List<Crud2> list = Datastore.query(meta).asList();
        for (Crud2 crud2 : list) {
            Datastore.delete(tx, crud2.getKey());
        }
    }

    private Crud2 createData(int i) {
        Crud2 crud2 = new Crud2();
        crud2.setTitle(getDataTitle(getDataNumber(i)));
        crud2.setContent(getDataContent(getDataNumber(i)));
        crud2.setDate(getDataDate(i));
        crud2.setNumber(getDataNumber(i));
        crud2.setFlag(getDataFlag(i));
        // System.out.println("createData="
        // + ToStringBuilder.reflectionToString(crud2));
        return crud2;
    }

    private Date getDataDate(int i) {
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.DATE, getDataNumber(i) - 5);
        DateUtil.clearTimePart(calendar);
        return calendar.getTime();
    }

    private boolean getDataFlag(int i) {
        return getDataNumber(i) % 2 == 0;
    }

    private int getDataNumber(int i) {
        return i;
    }

    private String getDataContent(int i) {
        return "content" + getDataNumber(i) + "CONTENT";
    }

    private String getDataTitle(int i) {
        return "title" + getDataNumber(i) + "TITLE";
    }

    @Test
    public void test() throws Exception {
        assertThat(service, is(notNullValue()));
    }

    @Test
    public void testGetAll() throws Exception {
        List<Crud2> list = service.getAll();
        assertNotNull(list);
        assertEquals(MAX_DATA, list.size());
    }

    @Test
    public void testGetList() throws Exception {
        Crud2Form form;
        List<Crud2> list;

        // all
        form = new Crud2Form();
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(MAX_DATA, list.size());

        // title
        form = new Crud2Form();
        form.setSearchTitle("e3TITL");
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(1, list.size());

        // content
        form = new Crud2Form();
        form.setSearchContent("t3CONTEN");
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(1, list.size());

        // date
        form = new Crud2Form();
        form.setSearchDateFrom(DateUtil.toString(getDataDate(2), "yyyy/MM/dd"));
        form.setSearchDateTo("");
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(8, list.size());

        form = new Crud2Form();
        list = service.getList(form);
        form.setSearchDateFrom("");
        form.setSearchDateTo(DateUtil.toString(getDataDate(3), "yyyy/MM/dd"));
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(4, list.size());

        form = new Crud2Form();
        form.setSearchDateFrom(DateUtil.toString(getDataDate(4), "yyyy/MM/dd"));
        form.setSearchDateTo(DateUtil.toString(getDataDate(8), "yyyy/MM/dd"));
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(5, list.size());

        // number
        form = new Crud2Form();
        form.setSearchNumberFrom("2");
        form.setSearchNumberTo("");
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(MAX_DATA - 2, list.size());

        form.setSearchNumberFrom("");
        form.setSearchNumberTo("3");
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(4, list.size());

        form.setSearchNumberFrom("3");
        form.setSearchNumberTo("6");
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(6 - 3 + 1, list.size());

        // flag
        form = new Crud2Form();
        form.setSearchFlag("true");
        list = service.getList(form);
        assertNotNull(list);
        assertEquals(MAX_DATA / 2, list.size());
    }
}
