library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.rtps_package.all;

package user_config is
    
    --*****USER CONFIG*****
    
    -- NOTE: All strings have to be padded to 256 characters
    
    -- Unicast IPv4 Address used by all RTPS Entities [Default 192.168.0.80]
    constant DEFAULT_IPv4_ADDRESS   : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := x"C0A80080";
    -- Number of RTPS Writer Endpoints
    constant NUM_WRITERS            : natural := 8;
    -- Number of RTPS Reader Endpoints
    constant NUM_READERS            : natural := 17;
    -- Number of RTPS Endpoints (Do not modify)
    constant NUM_ENDPOINTS          : natural := NUM_READERS+NUM_WRITERS;
    -- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
    constant PORT_CONFIG_PB         : natural := 7400;
    -- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)    
    constant PORT_CONFIG_DG         : natural := 250;
    -- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
    constant PORT_CONFIG_PG         : natural := 2; 
    -- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
    constant PORT_CONFIG_D0         : natural := 0; 
    -- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
    constant PORT_CONFIG_D1         : natural := 10;
    -- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)    
    constant PORT_CONFIG_D2         : natural := 1; 
    -- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
    constant PORT_CONFIG_D3         : natural := 11;
    -- MAC Address of underlying network stack (Used to generate GUIDs)
    constant MAC_ADDRESS            : std_logic_vector(47 downto 0) := x"97917E0BA8CF";
    -- Domain ID
    constant USER_DOMAIN_ID         : natural := 1;
    -- Domain TAG
    constant USER_DOMAIN_TAG        : USER_STRING_TYPE := "TEST_DOMAIN" & (12 to 256 => NUL);
    
    --***RTPS ENDPOINTS***
    -- Array denoting if Endpoints use Keyed Topics
    constant ENDPOINT_WITH_KEY             : USER_BOOLEAN_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => FALSE);
    -- Array mapping Topic Names to Endpoints
    constant ENDPOINT_TOPIC_STRING         : USER_STRING_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        2 => "TOPIC_2" & (8 to 256 => NUL),
        NUM_READERS+2 => "TOPIC_2" & (8 to 256 => NUL),
        others => "TOPIC_1" & (8 to 256 => NUL)
    );
    -- Array mapping Type Names to Endpoints
    constant ENDPOINT_TYPE_STRING          : USER_STRING_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        1 => "TYPE_2" & (7 to 256 => NUL),
        2 => "TYPE_2" & (7 to 256 => NUL),
        NUM_READERS+1 => "TYPE_2" & (7 to 256 => NUL),
        NUM_READERS+2 => "TYPE_2" & (7 to 256 => NUL),
        others => "TYPE_1" & (7 to 256 => NUL)
    );
    -- *TIMING CHARACTERISTICS*
    -- Timing Characteristics for Participant
    constant PARTICIPANT_ANNOUNCEMENT_PERIOD    : DURATION_TYPE := gen_duration(30,0); -- 30 s
    constant PARTICIPANT_LEASE_DURATION         : DURATION_TYPE := DEFAULT_PARTICIPANT_LEASE_DURATION;
    -- Denotes how much faster then the deadline/period we schedule in order to account for transport delay.
    constant DURATION_DELTA                     : DURATION_TYPE := gen_duration(0, 100*(10**6)); -- 100 ms
    -- Timing Characteristics for built-in Endpoints
    constant PARTICIPANT_HEARTBEAT_PERIOD               : DURATION_TYPE := gen_duration(1,0); -- 1 s
    constant PARTICIPANT_HEARTBEAT_RESPONSE_DELAY       : DURATION_TYPE := gen_duration(0,100*(10**6)); -- 100 ms
    constant PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY    : DURATION_TYPE := gen_duration(0,200*(10**6)); -- 200 ms
    constant PARTICIPANT_ACKNACK_RESPONSE_DELAY         : DURATION_TYPE := gen_duration(0,200*(10**6)); -- 200 ms
    constant PARTICIPANT_ACKNACK_SUPPRESSION_DELAY      : DURATION_TYPE := gen_duration(0,200*(10**6)); -- 200 ms
    -- Array mapping Timing Characteristics to Endpoints
    constant ENDPOINT_HEARTBEAT_PERIOD             : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => gen_duration(1,0)); -- 1 s
    constant ENDPOINT_HEARTBEAT_RESPONSE_DELAY     : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => gen_duration(0,100*(10**6))); -- 100 ms
    constant ENDPOINT_HEARTBEAT_SUPPRESSION_DELAY  : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => gen_duration(0,200*(10**6))); -- 200 ms
    constant ENDPOINT_ACKNACK_RESPONSE_DELAY       : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => gen_duration(0,200*(10**6))); -- 200 ms
    constant ENDPOINT_ACKNACK_SUPPRESSION_DELAY    : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => gen_duration(0,200*(10**6))); -- 200 ms
    
    
    --***ENDPOINT DDS QOS***
    -- Array mapping DURABILITY QoS to Endpoints
    constant ENDPOINT_DURABILITY_QOS           : USER_ENUMERATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        3 => TRANSIENT_LOCAL_DURABILITY_QOS,
        NUM_READERS+4 => TRANSIENT_LOCAL_DURABILITY_QOS,
        others => DEFAULT_DURABILITY_QOS
    );
    constant ENDPOINT_DURABILITY_SERVICE_CLEANUP_DELAY             : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => gen_duration(86400,0),
        others => DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY
    );
    constant ENDPOINT_DURABILITY_SERVICE_HISTORY                   : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => KEEP_ALL_HISTORY_QOS,
        others => DEFAULT_DURABILITY_SERVICE_HISTORY
    );
    constant ENDPOINT_DURABILITY_SERVICE_HISTORY_DEPTH             : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => std_logic_vector(to_unsigned(10, CDR_LONG_WIDTH)),
        others => DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH
    );
    constant ENDPOINT_DURABILITY_SERVICE_MAX_SAMPLES               : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => std_logic_vector(to_unsigned(10, CDR_LONG_WIDTH)),
        others => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES
    );
    constant ENDPOINT_DURABILITY_SERVICE_MAX_INSTANCES             : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH)),
        others => DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES
    );
    constant ENDPOINT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE  : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH)),
        others => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE
    );
    -- Array mapping PRESENTATION QoS to Endpoints
    constant ENDPOINT_PRESENTATION_QOS         : USER_ENUMERATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        4 => TOPIC_PRESENTATION_QOS,
        NUM_READERS+4 => TOPIC_PRESENTATION_QOS,
        NUM_READERS+5 => TOPIC_PRESENTATION_QOS,
        others => DEFAULT_PRESENTATION_QOS
    );
    constant ENDPOINT_COHERENT_ACCESS          : USER_BOOLEAN_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        5 => TRUE,
        6 => TRUE,
        NUM_READERS+4 => TRUE,
        NUM_READERS+5 => TRUE,
        others => DEFAULT_COHERENT_ACCESS
    );
    constant ENDPOINT_ORDERED_ACCESS           : USER_BOOLEAN_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        6 => TRUE,
        NUM_READERS+5 => TRUE,
        others => DEFAULT_ORDERED_ACCESS
    );
    -- Array mapping DEADLINE QoS to Endpoints
    constant ENDPOINT_DEADLINE_QOS             : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        7 => gen_duration(10,0),
        8 => gen_duration(20,0),
        NUM_READERS+4 => gen_duration(15,0),
        others => DEFAULT_DEADLINE_QOS
    );
    -- Array mapping LATENCY_BUDGET QoS to Endpoints
    constant ENDPOINT_LATENCY_BUDGET_QOS       : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        9 => gen_duration(0,500000000),
        10 => gen_duration(2,0),
        NUM_READERS+6 => gen_duration(1,0),
        others => DEFAULT_LATENCY_BUDGET_QOS
    );
    -- Array mapping OWNERSHIP QoS to Endpoints
    constant ENDPOINT_OWNERSHIP_QOS            : USER_ENUMERATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        others => DEFAULT_OWNERSHIP_QOS
    );
    -- Array mapping OWNERSHIP_STRENGTH QoS to Endpoints (Only relevant to Writers)
    constant ENDPOINT_OWNERSHIP_STRENGTH_QOS   : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => std_logic_vector(to_unsigned(2, CDR_LONG_WIDTH)),
        others => DEFAULT_OWNERSHIP_STRENGTH_QOS
    );
    -- Array mapping LIVELINESS QoS to Endpoints
    constant ENDPOINT_LIVELINESS_QOS           : USER_ENUMERATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        11 => MANUAL_BY_PARTICIPANT_LIVELINESS_QOS,
        12 => MANUAL_BY_TOPIC_LIVELINESS_QOS,
        NUM_READERS+4 => MANUAL_BY_PARTICIPANT_LIVELINESS_QOS,
        others => DEFAULT_LIVELINESS_QOS
    );
    constant ENDPOINT_LEASE_DURATION           : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        11 => gen_duration(20,0),
        12 => gen_duration(20,0),
        13 => gen_duration(10,0),
        14 => gen_duration(20,0),
        NUM_READERS+4 => gen_duration(15,0),
        others => DEFAULT_LEASE_DURATION
    );
    -- Array mapping TIME_BASED_FILTER QoS to Endpoints (Only relevant to Readers)
    constant ENDPOINT_TIME_BASED_FILTER_QOS    : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        7   => gen_duration(5,0),
        8   => gen_duration(5,0),
        others => DEFAULT_TIME_BASED_FILTER_QOS
    );
    -- XXX: PARTITION QoS Ignored
    -- Array mapping RELIABILITY QoS to Endpoints
    constant ENDPOINT_RELIABILITY_QOS          : USER_ENUMERATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        15 => BEST_EFFORT_RELIABILITY_QOS,
        NUM_READERS+3 => BEST_EFFORT_RELIABILITY_QOS,
        others => DEFAULT_RELIABILTY_QOS
    );
    -- (Only relevant to Writers)
    constant ENDPOINT_MAX_BLOCKING_TIME        : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => gen_duration(2,0),
        others => DEFAULT_MAX_BLOCKING_TIME
    );
    -- Array mapping TRANSPORT_PRIORITY QoS to Endpoints (Only relevant to Writers)
    constant ENDPOINT_TRANSPORT_PRIORITY_QOS   : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => std_logic_vector(to_unsigned(3, CDR_LONG_WIDTH)),
        others => DEFAULT_TRANSPORT_PRIORITY_QOS
    );
    -- Array mapping LIFESPAN QoS to Endpoints (Only relevant to Writers)
    constant ENDPOINT_LIFESPAN_QOS             : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        NUM_READERS+7   => gen_duration(30,0),
        others => DEFAULT_LIFESPAN_QOS
    );
    -- Array mapping DESTINATION_ORDER QoS to Endpoints
    constant ENDPOINT_DESTINATION_ORDER_QOS    : USER_ENUMERATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (
        16 => BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS,
        NUM_READERS+4 => BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS,
        others => DEFAULT_DESTINATION_ORDER_QOS
    );
    -- Array mapping HISTORY QoS to Endpoints
    constant ENDPOINT_HISTORY_QOS              : USER_ENUMERATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_HISTORY_QOS);
    constant ENDPOINT_HISTORY_DEPTH            : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_HISTORY_DEPTH);
    -- Array mapping RESOURCE_LIMITS QoS to Endpoints
    constant ENDPOINT_MAX_SAMPLES              : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_MAX_SAMPLES);
    constant ENDPOINT_MAX_INSTANCES            : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_MAX_INSTANCES);
    constant ENDPOINT_MAX_SAMPLES_PER_INSTANCE : USER_LONG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_MAX_SAMPLES_PER_INSTANCE);
    -- XXX: ENTITY_FACTORY QoS Ignored
    -- Array mapping WRITER_DATA_LIFECYCLE QoS to Endpoints (Only relevant to Writers)
    constant ENDPOINT_AUTODISPOSE_UNREGISTERED_INSTANCES   : USER_BOOLEAN_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_AUTODISPOSE_UNREGISTERED_INSTANCES);
    -- Array mapping Reader_DATA_LIFECYCLE QoS to Endpoints (Only relevant to Readers)
    constant ENDPOINT_AUTOPURGE_NOWRITER_SAMPLES_DELAY     : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_AUTOPURGE_NOWRITER_SAMPLES_DELAY);
    constant ENDPOINT_AUTOPURGE_DISPOSED_SAMPLES_DELAY     : USER_DURATION_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => DEFAULT_AUTOPURGE_DISPOSED_SAMPLES_DELAY);
    
    -- TESTING PARAMETERS
    constant TEST_STRING : string := "TEST_CONFIG_1";
    
end package;