package com.example.fuzzControll.service.impl;

import com.alibaba.fastjson2.JSON;
import com.example.fuzzControll.annotion.NeedCutAround;
import com.example.fuzzControll.annotion.NeedCutBefore;
import com.example.fuzzControll.conf.KittyProperties;
import com.example.fuzzControll.domain.bo.FuzzParams;
import com.example.fuzzControll.exception.testException.AflnetException;
import com.example.fuzzControll.exception.testException.CmdException;
import com.example.fuzzControll.exception.testException.FuzzException;
import com.example.fuzzControll.domain.bo.TestEntity;
import com.example.fuzzControll.service.FuzzParamsService;
import com.example.fuzzControll.service.GenerateMethodService;
import com.example.fuzzControll.tools.system.GlobalClass;
import com.example.fuzzControll.tools.test.TestCmdTools;
import com.example.fuzzControll.tools.test.TestTools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class GenerateMethodServiceImpl implements GenerateMethodService {
    TestCmdTools cmdTools = new TestCmdTools();
    @Autowired
    KittyProperties kitty;
    @Autowired
    FuzzParamsService fuzzParamsService;
    @Override
    @NeedCutAround(name ="kitty",function = "generation")
    public Map<String, List<String>> generation(TestEntity testEntity) throws FuzzException, CmdException {
        /*存入参数*/
//        int missionId = GlobalClass.missionInfoMapper.selectTopMissionId();
//        boolean flag = fuzzParamsService.saveFuzzParams(new FuzzParams(JSON.toJSONString(testEntity.getParamJson()), new Date(), missionId));
//        if (!flag) {
//            throw new AflnetException("Save params error!");
//        }
        /*运行指令*/
        String cmd = parseParameters(testEntity);
        if (cmd.isEmpty()) {
            throw new FuzzException("cmd is null ! The number of parameters does not match!");
        }
        return null;
    }

    public String parseParameters(TestEntity testEntity) {
        try {
            switch (testEntity.getTestClassName().toLowerCase()) {
                case "foreach":
                    return cmd(testEntity, "-f");
                case "repeat":
                    return cmd(testEntity, "-r");
                case "oneof":
                    return cmd(testEntity, "-o");
                case "switch":
                    return cmd(testEntity, "-s");
                case "pad":
                    return cmd(testEntity, "-p");
                case "template":
                    return cmd(testEntity, "-t");
                case "meta":
                    return cmd(testEntity, "-m");
                case "if":
                    return cmd(testEntity, "-c");
                case "ifnot":
                    return cmd(testEntity, "-e");
                case "trunc"://have error
                    return cmd(testEntity, "-u");
                default:
                    throw new FuzzException("Unknown method !");
            }
        } catch (FuzzException e) {
            throw new FuzzException("Unknown method !");
        }
    }

    private String cmd(TestEntity testEntity, String cmd) throws FuzzException {
        if (!TestTools.paramsLenghtTest(testEntity.getParamJson().length, 5, "generationMethod"))
            return "";
        String target_host = null;
        String target_port = null;
        String s1 = null;
        String s2 = null;
        String s3 = null;
        try {
            target_host = testEntity.getParamJson()[0];
            target_port = testEntity.getParamJson()[1];
            s1 = testEntity.getParamJson()[2];
            s2 = testEntity.getParamJson()[3];
            s3 = testEntity.getParamJson()[4];
        } catch (Exception e) {
            throw new FuzzException("Parameter parsing failed !");
        }
        return kitty.getVenvPath() + " " + kitty.getMethodPath() + "generate_method_test.py " + cmd + " " + s1 + " " + s2 + " " + s3 + " --host=" + target_host + " --port=" + target_port;
    }
}