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
    
    -- Period of system clock
    constant CLOCK_PERIOD               : time := 50 ns;
    -- Maximum number of supported remote Participants (Affects generated Memory Size)
    constant MAX_REMOTE_PARTICIPANTS    : natural := 50;
    -- Maximum number of supported remote Endpoints (Affects generated Memory Size)
    constant MAX_REMOTE_ENDPOINTS       : natural := 50;
    -- If Multicast Locators should be used instead of Unicast Locators
    constant PREFER_MULTICAST_LOCATORS  : boolean := FALSE;
    
    -- Unicast IPv4 Address used by all RTPS Entities [Default 192.168.0.128]
    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"17E97CEF2F64";
    -- Domain ID
    constant USER_DOMAIN_ID         : natural := 1;
    -- Domain TAG
    constant USER_DOMAIN_TAG        : USER_STRING_TYPE := gen_user_string("TEST_DOMAIN");
    
    -- *TIMING CHARACTERISTICS*
    -- Timing Characteristics for Participant
    constant PARTICIPANT_ANNOUNCEMENT_PERIOD    : DURATION_TYPE := gen_duration(30 sec);
    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(100 ms);
    -- Timing Characteristics for built-in Endpoints (Discovery Module)
    constant PARTICIPANT_HEARTBEAT_PERIOD               : DURATION_TYPE := gen_duration(1 sec);
    constant PARTICIPANT_HEARTBEAT_RESPONSE_DELAY       : DURATION_TYPE := gen_duration(100 ms);
    constant PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY    : DURATION_TYPE := gen_duration(200 ms);
    constant PARTICIPANT_ACKNACK_RESPONSE_DELAY         : DURATION_TYPE := gen_duration(200 ms);
    constant PARTICIPANT_ACKNACK_SUPPRESSION_DELAY      : DURATION_TYPE := gen_duration(200 ms);
    
    -- *ENDPOINT CONFIG*
    constant ENDPOINT_CONFIG : CONFIG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1); -- Deferred to Package Body
    
    -- Set to TRUE for Simulation Testing (Extra Code generated)
    constant SIMULATION_FLAG : boolean := TRUE;
    
    -- TESTING PARAMETERS
    constant TEST_STRING : string := "TEST_CONFIG_1";
end package;

package body user_config is

    function gen_config return CONFIG_ARRAY_TYPE is
        variable ret : CONFIG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1);
        variable c1, c2 : CONFIG_TYPE;
    begin
        
        c1  := DEFAULT_READER_CONFIG;        
        c1.WITH_KEY                     := FALSE;
        c1.PUSH_MODE                    := FALSE;
        c1.TOPICNAME                    := gen_user_string("TOPIC_1");
        c1.TYPENAME                     := gen_user_string("TYPE_1");
        c1.HEARTBEAT_RESPONSE_DELAY     := gen_duration(100 ms);
        c1.HEARTBEAT_SUPPRESSION_DELAY  := gen_duration(200 ms);
        c1.ACKNACK_RESPONSE_DELAY       := gen_duration(200 ms);
        c1.ACKNACK_SUPPRESSION_DELAY    := gen_duration(200 ms);
        c1.MAX_PAYLOAD_SIZE             := 8;
        
        c2  := DEFAULT_WRITER_CONFIG;
        c2.WITH_KEY                     := FALSE;
        c2.PUSH_MODE                    := FALSE;
        c2.TOPICNAME                    := gen_user_string("TOPIC_1");
        c2.TYPENAME                     := gen_user_string("TYPE_1");
        c2.HEARTBEAT_RESPONSE_DELAY     := gen_duration(100 ms);
        c2.HEARTBEAT_SUPPRESSION_DELAY  := gen_duration(200 ms);
        c2.ACKNACK_RESPONSE_DELAY       := gen_duration(200 ms);
        c2.ACKNACK_SUPPRESSION_DELAY    := gen_duration(200 ms);
        c1.MAX_PAYLOAD_SIZE             := 8;
        
        ret := (
            0 to NUM_READERS-1              => c1, 
            NUM_READERS to NUM_ENDPOINTS-1  => c2
        );
        
        ret(1).TYPENAME         := gen_user_string("TYPE_2");
        ret(2).TOPICNAME        := gen_user_string("TOPIC_2");
        ret(2).TYPENAME         := gen_user_string("TYPE_2");
        ret(3).DURABILITY_QOS   := TRANSIENT_LOCAL_DURABILITY_QOS;
        ret(4).PRESENTATION_QOS := TOPIC_PRESENTATION_QOS;
        ret(5).COHERENT_ACCESS  := TRUE;
        ret(6).COHERENT_ACCESS  := TRUE;
        ret(6).ORDERED_ACCESS   := TRUE;
        ret(7).DEADLINE_QOS             := gen_duration(10 sec);
        ret(7).TIME_BASED_FILTER_QOS    := gen_duration(5 sec);
        ret(8).DEADLINE_QOS             := gen_duration(20 sec);
        ret(8).TIME_BASED_FILTER_QOS    := gen_duration(5 sec);
        ret(9).LATENCY_BUDGET_QOS   := gen_duration(500 ms);
        ret(10).LATENCY_BUDGET_QOS  := gen_duration(2 sec);
        ret(11).LIVELINESS_QOS  := MANUAL_BY_PARTICIPANT_LIVELINESS_QOS;
        ret(11).LEASE_DURATION  := gen_duration(20 sec);
        ret(12).LIVELINESS_QOS  := MANUAL_BY_TOPIC_LIVELINESS_QOS;
        ret(12).LEASE_DURATION  := gen_duration(20 sec);
        ret(13).LEASE_DURATION  := gen_duration(10 sec);
        ret(14).LEASE_DURATION  := gen_duration(20 sec);
        ret(15).RELIABILITY_QOS := RELIABLE_RELIABILITY_QOS;
        ret(16).DESTINATION_ORDER_QOS   := BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS;
        ret(NUM_READERS+1).TYPENAME     := gen_user_string("TYPE_2");
        ret(NUM_READERS+2).TOPICNAME    := gen_user_string("TOPIC_2");
        ret(NUM_READERS+2).TYPENAME     := gen_user_string("TYPE_2");
        ret(NUM_READERS+3).RELIABILITY_QOS  := BEST_EFFORT_RELIABILITY_QOS;
        ret(NUM_READERS+4).DURABILITY_QOS           := TRANSIENT_LOCAL_DURABILITY_QOS;
        ret(NUM_READERS+4).PRESENTATION_QOS         := TOPIC_PRESENTATION_QOS;
        ret(NUM_READERS+4).COHERENT_ACCESS          := TRUE;
        ret(NUM_READERS+4).DEADLINE_QOS             := gen_duration(15 sec);
        ret(NUM_READERS+4).LIVELINESS_QOS           := MANUAL_BY_PARTICIPANT_LIVELINESS_QOS;
        ret(NUM_READERS+4).LEASE_DURATION           := gen_duration(15 sec);
        ret(NUM_READERS+4).DESTINATION_ORDER_QOS    := BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS;
        ret(NUM_READERS+5).PRESENTATION_QOS := TOPIC_PRESENTATION_QOS;
        ret(NUM_READERS+5).COHERENT_ACCESS  := TRUE;
        ret(NUM_READERS+5).ORDERED_ACCESS   := TRUE;
        ret(NUM_READERS+6).LATENCY_BUDGET_QOS   := gen_duration(1 sec);
        ret(NUM_READERS+7).DURABILITY_SERVICE_CLEANUP_DELAY             := gen_duration(86400 sec);
        ret(NUM_READERS+7).DURABILITY_SERVICE_HISTORY                   := KEEP_ALL_HISTORY_QOS;
        ret(NUM_READERS+7).DURABILITY_SERVICE_HISTORY_DEPTH             := std_logic_vector(to_unsigned(10, CDR_LONG_WIDTH));
        ret(NUM_READERS+7).DURABILITY_SERVICE_MAX_SAMPLES               := std_logic_vector(to_unsigned(10, CDR_LONG_WIDTH));
        ret(NUM_READERS+7).DURABILITY_SERVICE_MAX_INSTANCES             := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
        ret(NUM_READERS+7).DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE  := std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH));
        ret(NUM_READERS+7).OWNERSHIP_STRENGTH_QOS                       := std_logic_vector(to_unsigned(2, CDR_LONG_WIDTH));
        ret(NUM_READERS+7).MAX_BLOCKING_TIME                            := gen_duration(2 sec);
        ret(NUM_READERS+7).LIFESPAN_QOS                                 := gen_duration(30 sec);
        
        return ret;
    end function;
    
    constant ENDPOINT_CONFIG : CONFIG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := gen_config;
    
end package body;