package io.wdd.server.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.wdd.common.response.R;
import io.wdd.common.response.ResultStat;
import io.wdd.server.beans.po.ProjectInfoPO;
import io.wdd.server.beans.request.ProjectQueryEntity;
import io.wdd.server.beans.vo.ProjectInfoVO;
import net.datafaker.Faker;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

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

@SpringBootTest
public class ProjectInfoTest {

    @Resource
    ProjectController projectController;

    @Resource
    Faker fakeInstance;

    @Test
    public void test_projectGetAll_returnsNonNullObject() {
        R<List<ProjectInfoPO>> result = projectController.projectGetAll();
        assertNotNull(result);
    }

    @Test
    public void test_valid_input_values_for_mandatory_fields_only() {
        // Arrange
        ProjectQueryEntity projectQueryEntity = new ProjectQueryEntity();
        projectQueryEntity.setPageNumber(1);
        projectQueryEntity.setPageSize(10);

        // Act
        R<Page<ProjectInfoPO>> result = projectController.projectQueryOne(projectQueryEntity);

        // Assert
        assertNotNull(result);
        assertEquals(
                ResultStat.SUCCESS.getCode(),
                result.getCode()
        );
        assertNotNull(result.getData());
        assertEquals(
                1,
                result
                        .getData()
                        .getCurrent()
        );
        assertEquals(
                10,
                result
                        .getData()
                        .getSize()
        );
        assertNull(result
                           .getData()
                           .getRecords()
                           .get(0)
                           .getProjectName());
        assertNull(result
                           .getData()
                           .getRecords()
                           .get(0)
                           .getProjectProvince());
    }

    @Test
    public void test_empty_input_values() {
        // Arrange
        ProjectQueryEntity projectQueryEntity = new ProjectQueryEntity();

        // Act
        R<Page<ProjectInfoPO>> result = projectController.projectQueryOne(projectQueryEntity);

        // Assert
        assertNotNull(result);
        assertEquals(
                ResultStat.SUCCESS.getCode(),
                result.getCode()
        );
        assertNull(result.getData());
    }

    @Test
    public void test_valid_input_values_for_all_fields() {
        // Arrange
        ProjectQueryEntity projectQueryEntity = new ProjectQueryEntity();
        projectQueryEntity.setPageNumber(1);
        projectQueryEntity.setPageSize(10);
        projectQueryEntity.setProjectName("Test Project");
        projectQueryEntity.setProjectProvince("Test Province");

        // Act
        R<Page<ProjectInfoPO>> result = projectController.projectQueryOne(projectQueryEntity);

        // Assert
        assertNotNull(result);
        assertEquals(
                ResultStat.SUCCESS.getCode(),
                result.getCode()
        );
        assertNotNull(result.getData());
        assertEquals(
                1,
                result
                        .getData()
                        .getCurrent()
        );
        assertEquals(
                10,
                result
                        .getData()
                        .getSize()
        );
        assertEquals(
                "Test Project",
                result
                        .getData()
                        .getRecords()
                        .get(0)
                        .getProjectName()
        );
        assertEquals(
                "Test Province",
                result
                        .getData()
                        .getRecords()
                        .get(0)
                        .getProjectProvince()
        );
    }

    @Test
    public void test_projectCreate_returnsNonNullObjectWithExpectedMessage() {
        ProjectInfoVO projectInfoVO = new ProjectInfoVO();
        // Set projectInfoVO properties
        R<String> result = projectController.projectCreate(projectInfoVO);
        assertNotNull(result);
        assertEquals(
                "创建项目失败！",
                result.getData()
        );
    }

    @Test
    public void test_projectCreate_createWithRealData() {
        ProjectInfoVO projectInfoVO = new ProjectInfoVO();

        projectInfoVO.setProjectName("Test Project");
        projectInfoVO.setProjectProvince("Test Province");
        projectInfoVO.setProjectNamespace(fakeInstance.examplify("dasdcz"));
        projectInfoVO.setDeployNetEnv(fakeInstance
                                              .random()
                                              .nextInt(3));
        projectInfoVO.setDeployHardwareEnv(fakeInstance
                                                   .animal()
                                                   .name());
        // Set projectInfoVO properties
        R<String> result = projectController.projectCreate(projectInfoVO);
        assertNotNull(result);
        assertEquals(
                "创建项目成功！",
                result.getData()
        );
    }

    @Test
    public void test_projectCreate_createWithFakeData() {
        ProjectInfoVO projectInfoVO = new ProjectInfoVO();

        projectInfoVO.setProjectName(fakeInstance
                                             .funnyName()
                                             .name());
        projectInfoVO.setProjectNamespace(fakeInstance.examplify("dasdcz"));
        projectInfoVO.setDeployNetEnv(fakeInstance
                                              .random()
                                              .nextInt(3));
        projectInfoVO.setDeployHardwareEnv(fakeInstance
                                                   .animal()
                                                   .name());
        // Set projectInfoVO properties
        R<String> result = projectController.projectCreate(projectInfoVO);
        assertNotNull(result);
        assertEquals(
                "创建项目成功！",
                result.getData()
        );
    }

    @Test
    public void test_projectUpdate_returnsNonNullObjectWithExpectedMessage() {
        ProjectInfoPO projectInfoPO = new ProjectInfoPO();
        // Set projectInfoPO properties
        R<String> result = projectController.projectUpdate(projectInfoPO);
        assertNotNull(result);
        assertEquals(
                "更新项目失败！",
                result.getData()
        );
    }

    @Test
    public void test_projectDelete_returnsNonNullObjectWithExpectedMessage() {

        List<ProjectInfoPO> infoPOList = projectController
                .projectGetAll()
                .getData();

        int size = infoPOList.size();
        ProjectInfoPO infoPO = infoPOList
                .stream()
                .skip(fakeInstance
                              .random()
                              .nextInt(size))
                .findFirst()
                .get();

        System.out.println("infoPO to delete is = " + infoPO);

        R<String> result = projectController.projectDelete(infoPO.getProjectId());
        assertNotNull(result);
        assertEquals(
                "删除项目成功！",
                result.getData()
        );
    }


}
