package com.zsc.edu.gateway.service.iot;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zsc.edu.gateway.domain.iot.EventBuilder;
import com.zsc.edu.gateway.domain.iot.ServeBuilder;
import com.zsc.edu.gateway.exception.ConstraintException;
import com.zsc.edu.gateway.modules.iot.tsl.dto.ParamDto;
import com.zsc.edu.gateway.modules.iot.tsl.dto.EventDto;
import com.zsc.edu.gateway.modules.iot.tsl.entity.DataType;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Event;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Param;
import com.zsc.edu.gateway.modules.iot.tsl.entity.Event;
import com.zsc.edu.gateway.modules.iot.tsl.repo.EventRepository;
import com.zsc.edu.gateway.modules.iot.tsl.repo.ParamRepository;
import com.zsc.edu.gateway.modules.iot.tsl.service.EventService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
public class EventServiceTest {
    @Autowired
    private EventService service;
    @Autowired
    private EventRepository repo;
    @Autowired
    private ParamRepository paramRepo;

    private Event event1;
    private Event event2;

    @BeforeEach
    void setUp() {
        event1 = EventBuilder.builder().setName("EVENT_NAME_1").setIdentifier("测试1").setProductId(121L).setType(Event.Type.ACTIVE).build();
        repo.insert(event1);
        event2 = EventBuilder.builder().setName("EVENT_NAME_2").setIdentifier("测试2").setProductId(121L).setType(Event.Type.ACTIVE).build();
        repo.insert(event2);
    }

    @AfterEach
    void tearDown() {
        repo.delete(new LambdaQueryWrapper<Event>()
                .in(Event::getName, "EVENT_NAME_1", "EVENT_NAME_2", "EVENT_3", "EVENT_UPDATE"));
        paramRepo.delete(new LambdaQueryWrapper<Param>()
                .in(Param::getName, "联合测试1"));
    }

    @Test
    void list() {
        LambdaQueryWrapper<Event> queryWrapper = new LambdaQueryWrapper<>();
        assertEquals(2, service.list(queryWrapper.like(Event::getName, "EVENT")).size());
        assertEquals(1, service.list(queryWrapper.eq(Event::getName, event1.getName())).size());
//        assertEquals(2, service.list().size());
    }

    @Test
    void createProduct() {
        EventDto dto = new EventDto(121L, "EVENT_3", "测试3", "备注", Event.Type.ACTIVE, createParam());
        Event Event = service.create(dto);
        assertNotNull(Event);
        List<Event> events = service.list(new QueryWrapper<Event>().like("name", "EVENT"));
        assertEquals(3, events.size());
        // 不能创建其他已存在的同名同代码部门
        EventDto dto2 = new EventDto(121L, event2.getName(), "测试1", "备注", null, null);
        assertThrows(ConstraintException.class, () -> service.create(dto2));
    }

    @Test
    void updateProduct() {
        EventDto dto = new EventDto();
        dto.setName("EVENT_UPDATE");
        dto.setIdentifier("测试更新");
        dto.setProductId(121L);
        dto.setOutputs(createParam());
        service.update(dto, event2.getId());
        Event updatedServe = repo.selectOne(new LambdaQueryWrapper<Event>().eq(Event::getName, dto.getName()));
        assertNotNull(updatedServe);
        assertEquals("EVENT_UPDATE", updatedServe.getName());
        assertEquals(event2.getId(), updatedServe.getId());
    }


    public List<ParamDto> createParam() {
        ParamDto paramDto = new ParamDto();
        paramDto.setName("联合测试1");
        paramDto.setType(Param.Type.OUTPUT);
        paramDto.setDataType(DataType.DATE);
        List<ParamDto> params = new ArrayList<>();
        params.add(paramDto);
        return params;
    }
}
