package com.bs.mes.schedule.strategy;

import com.ximai.mes.pro.schedule.*;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentCapacity;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentDeliveryTime;
import com.ximai.mes.pro.schedule.strategy.EvaluateEquipmentSerial;
import org.junit.Assert;
import org.junit.Test;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class EvaluateEquipmentSerialTest {
    @Test public void evaluate(){
        EvaluateEquipmentSerial evaluateEquipmentSerial = new EvaluateEquipmentSerial();
        TaskSchedulingContext context = new TaskSchedulingContext();
        Equipment equipment1 = new Equipment();
        equipment1.setId(1L);
        equipment1.setSerial(1);
        Equipment equipment2 = new Equipment();
        equipment2.setId(2L);
        equipment2.setSerial(2);
        Equipment equipment3 = new Equipment();
        equipment3.setId(3L);
        equipment3.setSerial(3);
        Equipment equipment4 = new Equipment();
        equipment4.setId(4L);
        equipment4.setSerial(4);
        List<TaskSchedulingContext.TaskSchedulingResultContext> scheduleResult = new ArrayList<>();
        scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment1, null, null));
        scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment2, null, null));
        scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment3, null, null));
        scheduleResult.add(new TaskSchedulingContext.TaskSchedulingResultContext(equipment4, null, null));

        IOperationTimeCalculator.OperationTimePlan operationTimePlan = new IOperationTimeCalculator.OperationTimePlan();
        Job job = new Job("1", Duration.ofHours(5));
        LinkedList<Task> jobTasks = new LinkedList<>();
        jobTasks.add(new Task(1l, job));
        jobTasks.add(new Task(2l, job));
        jobTasks.add(new Task(3l, job));
        jobTasks.add(new Task(4l, job));
        jobTasks.add(new Task(5l, job));
        jobTasks.get(0).setWorkCenterId(1l);
        jobTasks.get(1).setWorkCenterId(1l);
        jobTasks.get(2).setWorkCenterId(2l);
        jobTasks.get(3).setWorkCenterId(3l);
        jobTasks.get(4).setWorkCenterId(4l);
        job.setTasks(jobTasks);
        Task currTask = jobTasks.get(1);
        context.setTask(currTask);
        context.setJob(job);
        context.setEquipment(equipment1);
        //2道序，设备1：0分、设备2：10分
        double rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment2);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(10, rst, 0.1);

        // 相同工作中心任务数超过设备数，重头开始计算
        jobTasks.add(new Task(6l, job));
        jobTasks.add(new Task(7l, job));
        jobTasks.add(new Task(8l, job));
        jobTasks.get(5).setWorkCenterId(1l);
        jobTasks.get(6).setWorkCenterId(1l);
        jobTasks.get(7).setWorkCenterId(1l);

        context.setTask(jobTasks.get(7));
        context.setEquipment(equipment1);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(10, rst, 0.1);

        //验证设备序号为空情况
        equipment3.setSerial(null);
        //任务1，匹配的设备1
        context.setTask(jobTasks.get(0));
        context.setEquipment(equipment1);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(10, rst, 0.1);
        context.setEquipment(equipment2);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment3);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment4);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);

        //任务2匹配设备2
        context.setTask(jobTasks.get(1));
        context.setEquipment(equipment1);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment2);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(10, rst, 0.1);
        context.setEquipment(equipment3);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment4);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);

        //任务6匹配设备4
        context.setTask(jobTasks.get(5));
        context.setEquipment(equipment1);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment2);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment3);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment4);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(10, rst, 0.1);

        //任务7匹配设备3
        context.setTask(jobTasks.get(6));
        context.setEquipment(equipment1);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment2);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);
        context.setEquipment(equipment3);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(10, rst, 0.1);
        context.setEquipment(equipment4);
        rst = evaluateEquipmentSerial.evaluate(context, operationTimePlan, scheduleResult);
        Assert.assertEquals(0, rst, 0.1);





    }
}
