/*
 *******************************************************************************
 * Copyright (c) 2018 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************
*/

package org.eclipse.openk.core.bpmn.gridmeasure.tasks.util;

import org.easymock.EasyMock;
import org.eclipse.openk.api.GridMeasure;
import org.eclipse.openk.api.SingleGridmeasure;
import org.eclipse.openk.api.Steps;
import org.eclipse.openk.common.mapper.GridMeasureMapper;
import org.eclipse.openk.core.bpmn.base.ProcessException;
import org.eclipse.openk.core.bpmn.gridmeasure.PlgmProcessState;
import org.eclipse.openk.core.bpmn.gridmeasure.PlgmProcessSubject;
import org.eclipse.openk.db.dao.AutoCloseEntityManager;
import org.eclipse.openk.db.dao.TblGridMeasureDao;
import org.eclipse.openk.db.dao.TblIdCounterDao;
import org.eclipse.openk.db.dao.TblSingleGridmeasureDao;
import org.eclipse.openk.db.dao.TblStepsDao;
import org.eclipse.openk.db.model.TblGridMeasure;
import org.eclipse.openk.db.model.TblIdCounter;
import org.eclipse.openk.db.model.TblSingleGridmeasure;
import org.eclipse.openk.db.model.TblSteps;
import org.junit.Ignore;
import org.junit.Test;
import org.powermock.api.easymock.PowerMock;
import org.powermock.reflect.Whitebox;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import java.util.ArrayList;
import java.util.List;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;

public class GridMeasureStorageHelperTest {
    class TestableStorageHelper extends GridMeasureStorageHelper {
        public TblGridMeasureDao dao;
        public TblSingleGridmeasureDao sgDao;
        public TblStepsDao stpDao;
        public TblIdCounterDao idCounterDao;
        public EntityManager em;

        private TestableStorageHelper() {
            super();
        }


        @Override
        protected EntityManager createEntityManager() {
            if (em != null) {
                return em;
            } else {
                return super.createEntityManager();
            }
        }

        @Override
        protected TblGridMeasureDao createTblGridMeasureDao(EntityManager em) {
            if (dao != null) {
                return dao;
            } else {
                return super.createTblGridMeasureDao(em);
            }
        }

        @Override
        protected TblSingleGridmeasureDao createTblSingleGridmeasureDao(EntityManager em) {
            if (sgDao != null) {
                return sgDao;
            } else {
                return super.createTblSingleGridmeasureDao(em);
            }
        }

        @Override
        protected TblStepsDao createTblStepsDao(EntityManager em) {
            if (stpDao != null) {
                return stpDao;
            } else {
                return super.createTblStepsDao(em);
            }
        }

        @Override
        protected TblIdCounterDao createTblIdCounterDao(EntityManager em) {
            if (idCounterDao != null) {
                return idCounterDao;
            } else {
                return super.createTblIdCounterDao(em);
            }
        }
    }

    private EntityManager createEM() {
        EntityTransaction et = EasyMock.createMock(EntityTransaction.class);
        et.begin();
        expectLastCall().andVoid().anyTimes();
        et.commit();
        expectLastCall().andVoid().anyTimes();
        et.rollback();
        expectLastCall().andVoid().anyTimes();

        EasyMock.replay(et);
        EasyMock.verify(et);

        EntityManager em = EasyMock.createMock(EntityManager.class);
        expect(em.getTransaction()).andReturn(et).anyTimes();

        expect(em.isOpen()).andReturn(false).anyTimes();


        em.close();
        expectLastCall().andVoid().anyTimes();

        EasyMock.replay(em);
        EasyMock.verify(em);

        return em;
    }

    @Test
    public void testGetTblGridMeasureDao() throws Exception {
        TestableStorageHelper task = new TestableStorageHelper();
        assertTrue(Whitebox.invokeMethod(task, "createTblGridMeasureDao", (EntityManager)null) instanceof TblGridMeasureDao);

        assertEquals( GridMeasureStorageHelper.class, GridMeasureStorageHelper.getHelper().getClass());
    }

    @Test
    public void testStoreMeasureInsert() throws Exception {
        EntityManager em = createEM();
        TblGridMeasure tblGridMeasure = new TblGridMeasure();
        TblGridMeasureDao mockedTblGridMeasureDao = EasyMock.createMock( TblGridMeasureDao.class );
        expect( mockedTblGridMeasureDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedTblGridMeasureDao.storeInTx(anyObject())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedTblGridMeasureDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedTblGridMeasureDao);
        EasyMock.verify(mockedTblGridMeasureDao);

        TestableStorageHelper task = new TestableStorageHelper();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);
        TblGridMeasure ret = Whitebox.invokeMethod(task, "storeMeasureImpl", tblGridMeasure,
                "fd", mockedTblGridMeasureDao, em);

    }

    @Test
    public void testGetNextDescriptiveId_existingCounter() throws Exception {
        EntityManager em = createEM();

        TblIdCounter counter = new TblIdCounter();
        counter.setId(1);
        counter.setCounter(3);
        counter.setModifiedDate("2018-08-20T16:00:00");

        TblGridMeasure tblGridMeasure = new TblGridMeasure();
        TblGridMeasureDao mockedTblGridMeasureDao = EasyMock.createMock( TblGridMeasureDao.class );
        expect( mockedTblGridMeasureDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedTblGridMeasureDao.storeInTx(anyObject())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedTblGridMeasureDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedTblGridMeasureDao);
        EasyMock.verify(mockedTblGridMeasureDao);

        TestableStorageHelper task = new TestableStorageHelper();
        task.idCounterDao = createTblIdCounterDaoMock(em, counter);
        Whitebox.invokeMethod(task, "getNextDescriptiveId", em, tblGridMeasure);
    }

    private TblIdCounterDao createTblIdCounterDaoMock(EntityManager em, TblIdCounter tblIdCounter) throws Exception {
        TblIdCounterDao mockedTblIdCounterDao = EasyMock.createMock( TblIdCounterDao.class );
        expect( mockedTblIdCounterDao.storeInTx(anyObject())).andReturn(new TblIdCounter()).anyTimes();
        expect( mockedTblIdCounterDao.getIdCounterForCounterType(anyObject())).andReturn(tblIdCounter).anyTimes();
        EasyMock.replay(mockedTblIdCounterDao);
        EasyMock.verify(mockedTblIdCounterDao);
        return mockedTblIdCounterDao;
    }

    @Test
    public void testStoreMeasureNullCreateDate() throws Exception {
        EntityManager em = createEM();
        TblGridMeasure tblGridMeasure = new TblGridMeasure();
        tblGridMeasure.setCreateDate(null);

        TblGridMeasureDao mockedDao = EasyMock.createMock( TblGridMeasureDao.class );
        expect( mockedDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.storeInTx(anyObject())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedDao);
        EasyMock.verify(mockedDao);

        TestableStorageHelper task = new TestableStorageHelper();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);
        TblGridMeasure ret = Whitebox.invokeMethod(task, "storeMeasureImpl", tblGridMeasure,
                "fd", mockedDao, em);

    }

    @Test
    public void testStoreMeasureUpdate() throws Exception {
        EntityManager em = createEM();
        TblGridMeasure tblGridMeasure = new TblGridMeasure();
        TblGridMeasureDao mockedDao = EasyMock.createMock( TblGridMeasureDao.class );
        expect( mockedDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.storeInTx(anyObject())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedDao);
        EasyMock.verify(mockedDao);

        GridMeasure gmViewModel = new GridMeasure();
        gmViewModel.setId(66);
        GridMeasureMapper gmMapper = new GridMeasureMapper();
        TestableStorageHelper task = new TestableStorageHelper();
        Whitebox.invokeMethod(task, "storeMeasureImpl", gmMapper.mapFromVModel(gmViewModel),
                "fd", mockedDao, em);
    }

    @Test( expected = ProcessException.class )
    public void testStoreMeasureUpdate_Fail() throws Exception {
        EntityManager em = createEM();
        TblGridMeasure tblGridMeasure = new TblGridMeasure();
        TblGridMeasureDao mockedDao = EasyMock.createMock( TblGridMeasureDao.class );
        expect( mockedDao.findByIdInTx(anyObject(), anyInt())).andReturn(null).anyTimes();
        expect( mockedDao.storeInTx(anyObject())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedDao);
        EasyMock.verify(mockedDao);

        GridMeasure gmViewModel = new GridMeasure();
        gmViewModel.setId(66);
        GridMeasureMapper gmMapper = new GridMeasureMapper();
        TestableStorageHelper task = new TestableStorageHelper();
        Whitebox.invokeMethod(task, "storeMeasureImpl", gmMapper.mapFromVModel(gmViewModel),
                "fd", mockedDao, em);

    }

    @Test(expected = ProcessException.class)
    public void testStoreMeasureUpdate_StoreException() throws Exception {
        EntityManager em = createEM();
        TblGridMeasure tblGridMeasure = new TblGridMeasure();
        TblGridMeasureDao mockedDao = EasyMock.createMock( TblGridMeasureDao.class );
        expect( mockedDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.storeInTx(anyObject())).andThrow(new Exception("mockedException")).anyTimes();
        expect( mockedDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedDao);
        EasyMock.verify(mockedDao);

        GridMeasure gmViewModel = new GridMeasure();
        gmViewModel.setId(66);
        GridMeasureMapper gmMapper = new GridMeasureMapper();
        TestableStorageHelper task = new TestableStorageHelper();
        Whitebox.invokeMethod(task, "storeMeasureImpl", gmMapper.mapFromVModel(gmViewModel),
                "fd", mockedDao, em);
    }

    private TestableStorageHelper prepareStoreMeasureFromViewModel() throws Exception{
        EntityManager em = createEM();

        TblGridMeasureDao mockedDao = EasyMock.createMock( TblGridMeasureDao.class );
        TblGridMeasure tblGridMeasure = new TblGridMeasure();

        expect( mockedDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.storeInTx(anyObject())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedDao);
        EasyMock.verify(mockedDao);

        // single grid measure
        TblSingleGridmeasure tblSingleGridmeasure = new TblSingleGridmeasure();
        tblSingleGridmeasure.setSortorder(1);
        TblSingleGridmeasureDao mockedSGmDao = EasyMock.createMock( TblSingleGridmeasureDao.class );
        expect( mockedSGmDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblSingleGridmeasure).anyTimes();
        expect( mockedSGmDao.storeInTx(anyObject())).andReturn(tblSingleGridmeasure).anyTimes();
        //expect( mockedSGmDao.removeInTx(anyObject(), anyInt()));

        mockedSGmDao.removeInTx(anyObject(), anyInt());
        expectLastCall().andVoid().anyTimes();

        expect( mockedSGmDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedSGmDao);
        EasyMock.verify(mockedSGmDao);

        // step
        TblSteps tblSteps = new TblSteps();
        tblSteps.setSortorder(1);
        TblStepsDao mockedStpDao = EasyMock.createMock( TblStepsDao.class );
        expect( mockedStpDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblSteps).anyTimes();
        expect( mockedStpDao.storeInTx(anyObject())).andReturn(tblSteps).anyTimes();

        mockedStpDao.removeInTx(anyObject(), anyInt());
        expectLastCall().andVoid().anyTimes();

        expect( mockedStpDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedStpDao);
        EasyMock.verify(mockedStpDao);

        TestableStorageHelper task = new TestableStorageHelper();

        task.em = em;
        task.dao = mockedDao;
        task.sgDao = mockedSGmDao;
        task.stpDao = mockedStpDao;

        return task;

    }

    @Test
    public void testStoreMeasureFromViewModel_noSingleGridmeasure() throws Exception {

        TestableStorageHelper task = prepareStoreMeasureFromViewModel();

        GridMeasure gmViewModel = new GridMeasure();
        List<SingleGridmeasure> sGmList = new ArrayList<SingleGridmeasure>();
        gmViewModel.setListSingleGridmeasures(sGmList);
        PlgmProcessSubject subject = PlgmProcessSubject.fromGridMeasure(gmViewModel, "fd");

        EntityManager em = createEM();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);

        Whitebox.invokeMethod(task, "storeMeasureFromViewModel", subject);

    }

    @Test
    public void testStoreMeasureFromViewModel_newSingleGridmeasure() throws Exception {

        TestableStorageHelper task = prepareStoreMeasureFromViewModel();

        GridMeasure gmViewModel = new GridMeasure();
        List<SingleGridmeasure> sGmList = new ArrayList<SingleGridmeasure>();
        sGmList.add(new SingleGridmeasure());
        gmViewModel.setListSingleGridmeasures(sGmList);
        PlgmProcessSubject subject = PlgmProcessSubject.fromGridMeasure(gmViewModel, "fd");

        EntityManager em = createEM();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);

        Whitebox.invokeMethod(task, "storeMeasureFromViewModel", subject);

    }

    @Test
    public void testStoreMeasureFromViewModel_withSingleGridmeasure_and_steps() throws Exception {

        TestableStorageHelper task = prepareStoreMeasureFromViewModel();

        GridMeasure gmViewModel = new GridMeasure();

        SingleGridmeasure sGmViewModel = new SingleGridmeasure();
        sGmViewModel.setId(5);
        List<SingleGridmeasure> sGmList = new ArrayList<SingleGridmeasure>();
        sGmList.add(sGmViewModel);
        gmViewModel.setListSingleGridmeasures(sGmList);

        Steps step = new Steps();
        step.setId(1);
        step.setSingleGridmeasureId(5);
        List<Steps> listSteps = new ArrayList<Steps>();
        listSteps.add(step);
        sGmViewModel.setListSteps(listSteps);

        PlgmProcessSubject subject = PlgmProcessSubject.fromGridMeasure(gmViewModel, "xx");

        EntityManager em = createEM();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);

        Whitebox.invokeMethod(task, "storeMeasureFromViewModel", subject);
    }

    @Test
    public void testStoreMeasureFromViewModel_deleteSingleGridmeasure() throws Exception {

        TestableStorageHelper task = prepareStoreMeasureFromViewModel();
        List<SingleGridmeasure> sGmList = new ArrayList<SingleGridmeasure>();

        GridMeasure gmViewModel = new GridMeasure();
        SingleGridmeasure sGmViewModel1 = new SingleGridmeasure();
        sGmViewModel1.setId(4);
        sGmViewModel1.setSortorder(1);
        sGmViewModel1.setDelete(false);
        sGmList.add(sGmViewModel1);

        SingleGridmeasure sGmViewModel2 = new SingleGridmeasure();
        sGmViewModel2.setId(5);
        sGmViewModel2.setSortorder(2);
        sGmViewModel2.setDelete(true);
        sGmList.add(sGmViewModel2);

        gmViewModel.setListSingleGridmeasures(sGmList);
        PlgmProcessSubject subject = PlgmProcessSubject.fromGridMeasure(gmViewModel, "xx");

        EntityManager em = createEM();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);

        Whitebox.invokeMethod(task, "storeMeasureFromViewModel", subject);
    }

    @Test
    public void testStoreMeasureFromViewModel_deleteStep() throws Exception {

        TestableStorageHelper task = prepareStoreMeasureFromViewModel();
        List<Steps> stpList = new ArrayList<Steps>();

        GridMeasure gmViewModel = new GridMeasure();

        List<SingleGridmeasure> sGmList = new ArrayList<SingleGridmeasure>();
        SingleGridmeasure sGmViewModel1 = new SingleGridmeasure();
        sGmViewModel1.setId(4);
        sGmViewModel1.setSortorder(1);
        sGmViewModel1.setDelete(false);
        sGmList.add(sGmViewModel1);

        Steps stpViewModel1 = new Steps();
        stpViewModel1.setId(4);
        stpViewModel1.setSortorder(1);
        stpViewModel1.setDelete(false);
        stpList.add(stpViewModel1);

        Steps stpViewModel2 = new Steps();
        stpViewModel2.setId(5);
        stpViewModel2.setSortorder(2);
        stpViewModel2.setDelete(true);
        stpList.add(stpViewModel2);

        sGmViewModel1.setListSteps(stpList);

        gmViewModel.setListSingleGridmeasures(sGmList);
        PlgmProcessSubject subject = PlgmProcessSubject.fromGridMeasure(gmViewModel, "xx");

        EntityManager em = createEM();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);

        Whitebox.invokeMethod(task, "storeMeasureFromViewModel", subject);
    }

    @Test
    public void testSetMeasureStatusAndStore() throws Exception {
        EntityManager em = createEM();
        TblGridMeasure tblGridMeasure = new TblGridMeasure();
        TblGridMeasureDao mockedDao = EasyMock.createMock( TblGridMeasureDao.class );
        expect( mockedDao.findByIdInTx(anyObject(), anyInt())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.storeInTx(anyObject())).andReturn(tblGridMeasure).anyTimes();
        expect( mockedDao.getEM()).andReturn(em).anyTimes();

        EasyMock.replay(mockedDao);
        EasyMock.verify(mockedDao);

        GridMeasure gmViewModel = new GridMeasure();
        PlgmProcessSubject subject = PlgmProcessSubject.fromGridMeasure(gmViewModel, "fd");
        GridMeasureMapper gmMapper = new GridMeasureMapper();
        TestableStorageHelper task = new TestableStorageHelper();
        task.em = em;
        task.dao = mockedDao;
        task.idCounterDao = createTblIdCounterDaoMock(em, null);

        Whitebox.invokeMethod(task, "setMeasureStatusAndStore", 66, "fd",
                PlgmProcessState.APPLIED);
    }

    @Test
    public void testStoreGridMeasure_WithSingleGridMEasuresBySorting() throws Exception {
        TestableStorageHelper task = prepareStoreMeasureFromViewModel();

        GridMeasure gmViewModel = new GridMeasure();
        List<SingleGridmeasure> sGmList = new ArrayList<SingleGridmeasure>();

        SingleGridmeasure sgm = new SingleGridmeasure();
        sgm.setId(1);
        sgm.setSortorder(2);
        java.time.LocalDateTime date1 = java.time.LocalDateTime.parse("2018-04-22T18:00:00");
        java.sql.Timestamp tsDate1 = java.sql.Timestamp.valueOf(date1);
        sgm.setPlannedStarttimeSinglemeasure(tsDate1);
        sgm.setTitle("title 1");

        SingleGridmeasure sgm2 = new SingleGridmeasure();
        sgm2.setId(2);
        sgm2.setSortorder(1);
        java.time.LocalDateTime date2 = java.time.LocalDateTime.parse("2018-02-22T18:00:00");
        java.sql.Timestamp tsDate2 = java.sql.Timestamp.valueOf(date2);
        sgm2.setPlannedStarttimeSinglemeasure(tsDate2);
        sgm2.setTitle("title 2");

        sGmList.add(sgm);
        sGmList.add(sgm2);
        gmViewModel.setListSingleGridmeasures(sGmList);
        PlgmProcessSubject subject = PlgmProcessSubject.fromGridMeasure(gmViewModel, "fd");

        EntityManager em = createEM();
        task.idCounterDao = createTblIdCounterDaoMock(em, null);

        Whitebox.invokeMethod(task, "storeMeasureFromViewModel", subject);

        assertEquals((Integer)gmViewModel.getListSingleGridmeasures().get(0).getSortorder(), (Integer)1);
        assertEquals(gmViewModel.getListSingleGridmeasures().get(0).getPlannedStarttimeSinglemeasure(), tsDate2);

        assertEquals((Integer)gmViewModel.getListSingleGridmeasures().get(1).getSortorder(), (Integer)2);
        assertEquals(gmViewModel.getListSingleGridmeasures().get(1).getPlannedStarttimeSinglemeasure(), tsDate1);
    }
}
