# ReplayRecord.java

    /*
     * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
     *
     * WSO2 LLC. licenses this file to you under the Apache License,
     * Version 2.0 (the "License"); you may not use this file except
     * in compliance with the License.
     * You may obtain a copy of the License at
     *
     * http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     */

    package org.apache.synapse.transport.http.conn;

    import java.util.Collections;
    import java.util.Map;

    /**
     * Represents a single replay record that encapsulates message content and
     * associated metadata for replay purposes.
     *
     * @see ReplayDataWriter for writing and persisting replay records.
     */
    public class ReplayRecord {

        /** Unique identifier for this message record. */
        private final String messageId;

        /** Metadata key-value pairs describing contextual properties of the replayed message. */
        private final Map<String, Object> metadata;

        /** Raw binary representation of the message content (headers, payload, etc.). */
        private final byte[] data;

        /**
         * Constructs a new replay record instance containing the unique message ID,
         * metadata, and raw data of the message.
         *
         * @param messageId a unique identifier for the replayed message; may not be null
         * @param metadata  map containing message context metadata; may be null if not applicable
         * @param data      byte array containing the message payload; may be null or empty
         */
        public ReplayRecord(String messageId, Map<String, Object> metadata, byte[] data) {
            this.messageId = messageId;
            this.data = (data != null) ? data.clone() : null;  // clone for data safety

            if (metadata != null) {
                // Wrap map unmodifiable to prevent changes from this instance,
                // but does not protect if original metadata map is mutated externally
                this.metadata = Collections.unmodifiableMap(metadata);
            } else {
                this.metadata = Collections.emptyMap();
            }
        }

        /**
         * Returns the unique identifier associated with this replay record.
         *
         * @return message ID string
         */
        public String getMessageId() {
            return messageId;
        }

        /**
         * Returns metadata associated with this record.
         * The metadata includes contextual information such as API name, version,
         * transport headers, or other attributes recorded at replay capture time.
         *
         * @return metadata map, or null if no metadata is available
         */
        public Map<String, Object> getMetadata() {
            return metadata;
        }

        /**
         * Returns the raw binary message data contained in this record.
         *
         * @return byte array of message data, or null if not set
         */
        public byte[] getData() {
            return data != null ? data.clone() : null;
        }
    }