package com.lemon.utils;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.lemon.constants.Constants;
import com.lemon.pojo.API;
import com.lemon.pojo.Case;
import com.lemon.pojo.Parameter;
import com.lemon.pojo.WriteBackData;
import org.apache.poi.ss.usermodel.*;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: Lemon
 * @description:
 * @author: ray
 * @create: 2022-09-23 14:23
 **/

public class ExcelUtils {

    //读取Excel中第1个sheet，API数据
    public static List<API> apiList = read(0, API.class);
    //读取Excel中第2个sheet，Case数据
    public static List<Case> caseList = read(1, Case.class);

    // 读取excel中第3个sheet页，Parameter数据
    public static List<Parameter> parameterList = read(2, Parameter.class);
    //回写Excel数据集合
    public static List<WriteBackData> wbdList = new ArrayList<>();


    public static <E> List<E> read(int startSheetIndex, Class<E> clazz) {
        //        定义泛型                            决定E的类型
        FileInputStream fis = null;
        try {
            // 1、创建流，加载Excel文件
            fis = new FileInputStream(Constants.EXCEL_PATH);
            // 2、导入配置，创建空对象相当于用默认配置
            ImportParams params = new ImportParams();
            // 3、设置sheet页
            params.setStartSheetIndex(startSheetIndex);
            // 4、是否需要进行excel验证，判断某个字段是否为空，若为空则过滤
            params.setNeedVerify(true);
            // 4、执行导入excel文件
            List<E> list = ExcelImportUtil.importExcel(fis, clazz, params);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(fis);
        }
        return null;
    }

    /**
     * 流关闭方法
     *
     * @param stream
     */
    private static void close(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /*
     * 批量回写
     */

    // 不用传参，因为集合为静态方法，修改Excel需要用到原生的poi
    public static void batchWrite() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(Constants.EXCEL_PATH);
            Workbook workbook = WorkbookFactory.create(fis);
            Sheet sheet = workbook.getSheetAt(1);
            //回写操作行和列
            //1、遍历wbdList集合
            for (WriteBackData wbd : wbdList) {
                //2、获取行号，根据行号获取row对象
                int rowNum = wbd.getRowNum();
                Row row = sheet.getRow(rowNum);
                //3、获取列号，根据列号获取cell对象
                int cellNum = wbd.getCellNum();
                Cell cell = row.getCell(cellNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                //4、获取回写内容，设置到cell中
                cell.setCellType(CellType.STRING);
                String content = wbd.getContent();
                // 5、将数据设置到Excel对应行和列中
                cell.setCellValue(content);
            }
            fos = new FileOutputStream(Constants.EXCEL_PATH);
            workbook.write(fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(fis);
            close(fos);
        }
    }


    /*
     * 从已经读取很多所有list<API>和所有list<Case>
     * 两个集合中获取符合条件的数据
     */
    public static Object[][] getAPIAndCaseByApiId(String apiId) {
        // 需要API对象
        API wantAPI = null;
        // 需要Case集合
        ArrayList<Case> wantCaseList = new ArrayList<>();
        // 匹配API对象
        for (API api : apiList) {
            //如果apiId和api集合中的apiId相等则返回
            if (apiId.equals(api.getId())) {
                wantAPI = api;
                break;
            }
        }
        // 匹配Case对象
        for (Case aCase : caseList) {
            //如果apiId和case集合中的apiId相等则返回
            if (apiId.equals(aCase.getApiID())) {
                wantCaseList.add(aCase);
            }
            //从parameter参数替换中将数据替换到case中
            for (Parameter parameter : parameterList) {
                if (aCase.getParams().contains(parameter.getParams())) {
                    String params = parameter.getParams();
                    String replace = aCase.getParams().replace(params, parameter.getData());
                    aCase.setParams(replace);    // 替换到参数中
                }
                if (aCase.getCheckSQL() != null && aCase.getCheckSQL().contains(parameter.getParams())) {
                    String params = parameter.getParams();
                    String replacesql = aCase.getCheckSQL().replace(params, parameter.getData());
                    aCase.setCheckSQL(replacesql);  // 替换到A段校验sql中
                }
                if (aCase.getCheckBSQL() != null && aCase.getCheckBSQL().contains(parameter.getParams())) {
                    String params = parameter.getParams();
                    String replacebsql = aCase.getCheckBSQL().replace(params, parameter.getData());
                    aCase.setCheckBSQL(replacebsql); // 替换到B段校验sql中
                }
            }
        }
        // wantCaselist和wantAPI是有关联的，他们的apiId相等。一个API接口对应多条Case
        Object[][] datas = new Object[wantCaseList.size()][2];
        // 往二维数组中存储API和Case数据，存几次由Case决定
        for (int i = 0; i < wantCaseList.size(); i++) {
            datas[i][0] = wantAPI;
            datas[i][1] = wantCaseList.get(i);
        }
        return datas;
    }


    public static Object[][] readTwo() {
        FileInputStream fis = null;
        Object[][] datas = null;
        try {
            fis = new FileInputStream(Constants.EXCEL_PATH);
            Workbook workbook = WorkbookFactory.create(fis);
            Sheet sheet = workbook.getSheetAt(0);
            int lastRowNum = sheet.getLastRowNum();
            //跳过表头第一行，从1开始取值
            datas = new Object[lastRowNum][4]; // 后面有几个参数写死
            for (int i = 1; i <= lastRowNum; i++) {
                Row row = sheet.getRow(i);
                // 获取URL
                Cell urlCell = row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                urlCell.setCellType(CellType.STRING);
                String urlValue = urlCell.getStringCellValue();
                datas[i - 1][0] = urlValue;
                // 获取type
                Cell typeCell = row.getCell(3, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                typeCell.setCellType(CellType.STRING);
                String typeValue = typeCell.getStringCellValue();
                datas[i - 1][1] = typeValue;
                // 获取 params
                Cell paramsCell = row.getCell(3, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                paramsCell.setCellType(CellType.STRING);
                String paramsValue = paramsCell.getStringCellValue();
                datas[i - 1][2] = paramsValue;
                // 获取 content-type
                Cell contentTypeCell = row.getCell(4, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                contentTypeCell.setCellType(CellType.STRING);
                String contentTypeValue = contentTypeCell.getStringCellValue();
                datas[i - 1][3] = contentTypeValue;
//                System.out.println("url:" + urlValue + ",type:" + typeValue + ",params:" + paramsValue + ",content-type:" + contentTypeValue);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return datas;
    }

    public static void main(String[] args) throws Exception {
        List<API> apiList = read(0, API.class);
        List<Case> caseList = read(1, Case.class);
        List<Parameter> parameterList = read(2, Parameter.class);
        System.out.println(parameterList);
    }


}
