package io.renren.dds;/*
 *
 *
 * Distributed under the OpenDDS License.
 * See: http://www.opendds.org/license.html
 */

import DDS.*;
import Messenger.*;
import OpenDDS.DCPS.*;
import org.omg.CORBA.StringSeqHolder;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
public class TestSubscriber {
    private DomainParticipantFactory dpf;
    private DomainParticipant dp;
    private MessageTypeSupportImpl servant;
    private Topic top;
    private Subscriber sub;
    private DataReaderQos dr_qos;
    private DataReaderQosHolder qosh;
    public DataReaderListenerImpl listener;
    private DataReader dr;
    private StatusCondition sc;
    private WaitSet ws;
    private SubscriptionMatchedStatusHolder matched;
    private Duration_t timeout;
    // 添加线程控制相关成员
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private volatile boolean running = true;

    public static boolean checkReliable(String[] args) {
        for (int i = 0; i < args.length; ++i) {
            if (args[i].equals("-r")) {
                return true;
            }
        }
        return false;
    }
    public TestSubscriber() throws Exception {
        String[] s = new String[6];
//        String[] s = new String[4];
        s[0] = "-DCPSBit";               // 启用Bit通信（保持原有配置）
        s[1] = "0";                      // Bit值
        s[2] = "-DCPSDefaultDiscovery";  // 指定发现机制为InfoRepo
//        s[0] = "-DCPSBit";
//        s[1] = "0";
//        s[2] = "-DCPSConfigFile";
//        s[3] = "C:/software/OpenDDS-3.16/java/tests/messenger/tcp.ini";
        s[3] = "DEFAULT_REPO";           // 使用集中式InfoRepo
        s[4] = "-DCPSInfoRepo";          // InfoRepo的corbaloc地址
        s[5] = "corbaloc:iiop:192.168.5.22:12345/DCPSInfoRepo"; // 替换为实际IP和端口
        executor.submit(() -> initialize(s)); // 初始化放在后台线程
    }
    public String getText(){
        return listener.text;
    }
    private void initialize(String[] args) {
        try {
            // ... 保持原有初始化代码到创建DataReader为止...

            System.out.println("Start Subscriber");
            boolean reliable = checkReliable(args);

            dpf = TheParticipantFactory.WithArgs(new StringSeqHolder(args));
            if (dpf == null) {
                System.err.println("ERROR: Domain Participant Factory not found");
                return;
            }
            dp = dpf.create_participant(4,
                    PARTICIPANT_QOS_DEFAULT.get(), null, DEFAULT_STATUS_MASK.value);
            if (dp == null) {
                System.err.println("ERROR: Domain Participant creation failed");
                return;
            }

            servant = new MessageTypeSupportImpl();
            if (servant.register_type(dp, "") != RETCODE_OK.value) {
                System.err.println("ERROR: register_type failed");
                return;
            }
            top = dp.create_topic("Movie Discussion List",
                    servant.get_type_name(),
                    TOPIC_QOS_DEFAULT.get(),
                    null,
                    DEFAULT_STATUS_MASK.value);
            if (top == null) {
                System.err.println("ERROR: Topic creation failed");
                return;
            }

            sub = dp.create_subscriber(SUBSCRIBER_QOS_DEFAULT.get(),
                    null, DEFAULT_STATUS_MASK.value);
            if (sub == null) {
                System.err.println("ERROR: Subscriber creation failed");
                return;
            }

            // Use the default transport (do nothing)

            dr_qos = new DataReaderQos();
            dr_qos.durability = new DurabilityQosPolicy();
            dr_qos.durability.kind = DurabilityQosPolicyKind.from_int(0);
            dr_qos.deadline = new DeadlineQosPolicy();
            dr_qos.deadline.period = new Duration_t();
            dr_qos.latency_budget = new LatencyBudgetQosPolicy();
            dr_qos.latency_budget.duration = new Duration_t();
            dr_qos.liveliness = new LivelinessQosPolicy();
            dr_qos.liveliness.kind = LivelinessQosPolicyKind.from_int(0);
            dr_qos.liveliness.lease_duration = new Duration_t();
            dr_qos.reliability = new ReliabilityQosPolicy();
            dr_qos.reliability.kind = ReliabilityQosPolicyKind.from_int(0);
            dr_qos.reliability.max_blocking_time = new Duration_t();
            dr_qos.destination_order = new DestinationOrderQosPolicy();
            dr_qos.destination_order.kind = DestinationOrderQosPolicyKind.from_int(0);
            dr_qos.history = new HistoryQosPolicy();
            dr_qos.history.kind = HistoryQosPolicyKind.from_int(0);
            dr_qos.resource_limits = new ResourceLimitsQosPolicy();
            dr_qos.user_data = new UserDataQosPolicy();
            dr_qos.user_data.value = new byte[0];
            dr_qos.ownership = new OwnershipQosPolicy();
            dr_qos.ownership.kind = OwnershipQosPolicyKind.from_int(0);
            dr_qos.time_based_filter = new TimeBasedFilterQosPolicy();
            dr_qos.time_based_filter.minimum_separation = new Duration_t();
            dr_qos.reader_data_lifecycle = new ReaderDataLifecycleQosPolicy();
            dr_qos.reader_data_lifecycle.autopurge_nowriter_samples_delay = new Duration_t();
            dr_qos.reader_data_lifecycle.autopurge_disposed_samples_delay = new Duration_t();
            dr_qos.representation = new DataRepresentationQosPolicy();
            dr_qos.representation.value = new short[0];

            qosh = new DataReaderQosHolder(dr_qos);
            sub.get_default_datareader_qos(qosh);
            if (reliable) {
                qosh.value.reliability.kind =
                        ReliabilityQosPolicyKind.RELIABLE_RELIABILITY_QOS;
            }
            qosh.value.history.kind = HistoryQosPolicyKind.KEEP_ALL_HISTORY_QOS;

            listener = new DataReaderListenerImpl();
            dr = sub.create_datareader(top,
                    qosh.value,
                    listener,
                    DEFAULT_STATUS_MASK.value);
            if (dr == null) {
                System.err.println("ERROR: DataReader creation failed");
                return;
            }

            sc = dr.get_statuscondition();
            sc.set_enabled_statuses(SUBSCRIPTION_MATCHED_STATUS.value);
            ws = new WaitSet();
            ws.attach_condition(sc);
            matched = new SubscriptionMatchedStatusHolder(new SubscriptionMatchedStatus());

//        timeout = new Duration_t(DURATION_INFINITE_SEC.value,
//                DURATION_INFINITE_NSEC.value);

            boolean matched_pub = false;


             timeout = new Duration_t(1, 0); // 1秒超时

            while (running) {
                final int result = dr.get_subscription_matched_status(matched);
                if (result != RETCODE_OK.value) {
                    System.err.println("ERROR: get_subscription_matched_status() failed");
                    break;
                }

                if (matched.value.current_count > 0) {
                    System.out.println("Subscriber Matched");
                    break;
                }

                ConditionSeqHolder cond = new ConditionSeqHolder(new Condition[]{});
                if (ws.wait(cond, timeout) != RETCODE_OK.value && running) {
                    System.err.println("ERROR: wait() failed");
                    break;
                }
            }

            System.out.println("Subscriber initialization completed");

        } catch (Exception e) {
            if (running) {
                e.printStackTrace();
            }
        }
    }

}
