import java.util.*;import java.util.stream.Collectors;import org.apache.commons.collections4.*;import org.apache.commons.lang3.*;
import cn.jojo.cc.biz.service.english.segment.*;import cn.jojo.cc.common.enums.*;import cn.jojo.cc.common.dto.english.*;import cn.jojo.cc.common.dto.question.library.*;import cn.jojo.cc.core.domain.english.*;import cn.jojo.cc.core.domain.question.library.*;import cn.jojo.cc.biz.model.cache.*;
public class ResponseBindingProbe {
 EnglishSegmentDeliveryBizService englishSegmentDeliveryBizService;
 static class Log{void error(String x,Object...y){}}Log log=new Log();
 void apply(List<StandardQuestionDto> questions,Map<String,SelectedSegmentOutput> selected){try{var m=Arrays.stream(getClass().getDeclaredMethods()).filter(x->x.getName().equals("fillSegments")).findFirst().get();m.setAccessible(true);if(m.getParameterCount()==2)m.invoke(this,questions,selected);else m.invoke(this,questions);}catch(Exception e){throw new RuntimeException(e);}}
 static void set(Object o,String n,Object v){try{var f=o.getClass().getDeclaredField(n);f.setAccessible(true);f.set(o,v);}catch(Exception e){throw new RuntimeException(e);}}
 static boolean has(Object o,String n){try{o.getClass().getDeclaredField(n);return true;}catch(Exception e){return false;}}
 static int failures;static void check(boolean b,String name){System.out.println((b?"PASS ":"FAIL ")+name);if(!b)failures++;}
    private void fillSegments(List<StandardQuestionDto> questions,
        Map<String, cn.jojo.cc.biz.service.english.segment.SelectedSegmentOutput> selectedOutputs) {
        if (CollectionUtils.isEmpty(questions)) {
            return;
        }
        try {
            Set<String> keys = questions.stream()
                .filter(e -> Objects.nonNull(e) && StringUtils.isNotBlank(e.getQuestionKey()))
                .map(StandardQuestionDto::getQuestionKey)
                .collect(Collectors.toSet());
            Map<String, EnglishSegmentDto> segmentsMap =
                englishSegmentDeliveryBizService.resolveByQuestionKeys(keys, selectedOutputs);
            if (MapUtils.isEmpty(segmentsMap)) {
                return;
            }
            questions.stream()
                .filter(e -> Objects.nonNull(e) && StringUtils.isNotBlank(e.getQuestionKey()))
                .forEach(question -> question.setSegments(segmentsMap.get(question.getQuestionKey())));
        } catch (Exception e) {
            log.error("装配英文划词失败，本次不下发 segments, size={}", questions.size(), e);
        }
    }public static void main(String[]args){
 var v1=com.alibaba.fastjson.JSON.parseObject("{\"questionInfo\":{\"material\":\"v1\"},\"explicitNull\":null}");var v2=com.alibaba.fastjson.JSON.parseObject("{\"questionInfo\":{\"material\":\"v2\"},\"explicitNull\":null}");
 String h1=SegmentPayloadIdentity.hash(v1),h2=SegmentPayloadIdentity.hash(v2);
 check(!h1.equals(h2),"different generation input has different identity");
 check(h1.equals(SegmentPayloadIdentity.hash(com.alibaba.fastjson.JSON.parseObject("{\"explicitNull\":null,\"questionInfo\":{\"material\":\"v1\"}}"))),"canonical ignores object key order");
 check(!h1.equals(SegmentPayloadIdentity.hash(com.alibaba.fastjson.JSON.parseObject("{\"questionInfo\":{\"material\":\"v1\"}}"))),"canonical preserves explicit null versus absent");
 check(!SegmentPayloadIdentity.hash(com.alibaba.fastjson.JSON.parseObject("{\"a\":[1,2]}" )).equals(SegmentPayloadIdentity.hash(com.alibaba.fastjson.JSON.parseObject("{\"a\":[2,1]}"))),"canonical preserves array order");
 var cache=new FormAndDataCacheBo();cache.setBusinessId(8L);cache.setSegmentSourceFormDataId(7L);cache.setSegmentSourcePayloadHash(h1);cache.setOutDataJson("/v1.json");cache.setOutDataJsonObj(v1);cache.setSegmentSourceOutputHash(SegmentPayloadIdentity.outputHash(v1));
 SelectedSegmentOutput selectedV1=SelectedSegmentOutput.capture(DataBaseTypeEnum.TEACHING,8L,cache,"/v1.json");
 // Freeze v1 credentials first; then the DB and stored sequence advance to v2.
 cache.setSegmentSourcePayloadHash(h2);cache.setOutDataJson("/v2.json");cache.setOutDataJsonObj(v2);cache.setSegmentSourceOutputHash(SegmentPayloadIdentity.outputHash(v2));
 var row=new QuestionSegmentDo();row.setQuestionKey("q1");row.setQuestionId(1L);row.setContentType(1);row.setSegmentStatus(0);row.setSourceTextMd5(cn.jojo.cc.biz.utils.MD5Util.creatMd5("v2"));
 var stored=com.alibaba.fastjson.JSON.parseObject("{\"matches\":[{\"text\":\"v2\",\"type\":\"word\"}]}");stored.put("sourcePayloadHash",h2);stored.put("sourceFormDataId",7L);stored.put("sourceContentConfigId",8L);stored.put("sourceOutputPayloadHash",SegmentPayloadIdentity.outputHash(v2));row.setSegments(stored.toJSONString());
 var core=new cn.jojo.cc.core.service.english.QuestionSegmentCoreService();core.rows=List.of(row);
 var delivery=new EnglishSegmentDeliveryBizService();set(delivery,"questionSegmentCoreService",core);set(delivery,"englishDictConfig",new cn.jojo.cc.biz.common.config.EnglishDictConfig());set(delivery,"segmentMatchIdResolver",new SegmentMatchIdResolver());
 if(has(delivery,"questionCoreService")){var questions=new cn.jojo.cc.core.service.question.library.QuestionCoreService();var q=new QuestionDo();q.setId(1L);q.setQuestionKey("q1");questions.current=q;set(delivery,"questionCoreService",questions);var content=new SegmentContentSnapshotService();set(content,"segmentTextExtractor",new SegmentTextExtractor(){public Map<Integer,List<String>> extractRichTextsByContentType(QuestionDo x){return Map.of(1,List.of("v2"));}public String extractPlainText(String x){return x;}});set(delivery,"segmentContentSnapshotService",content);}
 var rpc=new ResponseBindingProbe();rpc.englishSegmentDeliveryBizService=delivery;var dto=new StandardQuestionDto();dto.setQuestionKey("q1");rpc.apply(List.of(dto),Map.of("q1",selectedV1));check(dto.getSegments()==null,"select v1 then DB/segments v2 then fill: no mismatched segments");
 var selectedV2=SelectedSegmentOutput.capture(DataBaseTypeEnum.TEACHING,8L,cache,"/v2.json");dto=new StandardQuestionDto();dto.setQuestionKey("q1");rpc.apply(List.of(dto),Map.of("q1",selectedV2));check(dto.getSegments()!=null,"same selected v2 and v2 sequence remains deliverable");
 cache.setSegmentSourcePayloadHash(null);var legacy=SelectedSegmentOutput.capture(DataBaseTypeEnum.TEACHING,8L,cache,"/v2.json");dto=new StandardQuestionDto();dto.setQuestionKey("q1");rpc.apply(List.of(dto),Map.of("q1",legacy));check(dto.getSegments()==null,"legacy cache without reliable metadata fails closed");
 check(SelectedSegmentOutput.capture(DataBaseTypeEnum.TEACHING,9L,cache,"/v2.json")==null,"content config mismatch rejected");
 if(failures>0)System.exit(1);
 }}