/**
 *  Copyright (c) 2009, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  Licensed 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.passthru;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class PassThroughConstants {

    public static final int DEFAULT_IO_THREAD_COUNT = Runtime.getRuntime().availableProcessors();
    public static final int DEFAULT_MAX_CONN_PER_HOST_PORT = Integer.MAX_VALUE;
    
    public static final String REQUEST_MESSAGE_CONTEXT = "REQUEST_MESSAGE_CONTEXT";
    public static final String RESPONSE_MESSAGE_CONTEXT = "RESPONSE_MESSAGE_CONTEXT";
    public static final String SYNAPSE_ARTIFACT_TYPE = "SYNAPSE_ARTIFACT_TYPE";
    public static final String CONNECTION_POOL = "CONNECTION_POOL";
    public static final String TUNNEL_HANDLER = "TUNNEL_HANDLER";
    public static final String CONNECTION_INIT_TIME = "CONNECTION_INIT_TIME";
    // The time at which the connection is removed from the connection pool.
    // This is calculated using the keep alive timeout or connection idle time.
    public static final String CONNECTION_EXPIRY_TIME = "CONNECTION_EXPIRY_TIME";
    // The time after which the connection will be closed by the backend.
    // This time is mentioned as an HTTP header in the response from the backend.
    public static final String CONNECTION_KEEP_ALIVE_TIME_OUT = "CONNECTION_KEEP_ALIVE_TIME_OUT";

    public static final String TRUE = "TRUE";
    public static final String VALUE_FALSE = "false";

    public static final String FAULT_MESSAGE = "FAULT_MESSAGE"; // corresponds with BaseConstants
    public static final String FAULTS_AS_HTTP_200 = "FAULTS_AS_HTTP_200";
    public static final String SC_ACCEPTED = "SC_ACCEPTED";
    public static final String HTTP_SC = "HTTP_SC";
    public static final String FORCE_HTTP_1_0 = "FORCE_HTTP_1.0";
    public static final String DISABLE_CHUNKING = "DISABLE_CHUNKING";
    public static final String FULL_URI = "FULL_URI";
    public static final String NO_KEEPALIVE = "NO_KEEPALIVE";
    public static final String DISABLE_KEEPALIVE = "http.connection.disable.keepalive";
    public static final String IGNORE_SC_ACCEPTED = "IGNORE_SC_ACCEPTED";
    public static final String FORCE_SC_ACCEPTED = "FORCE_SC_ACCEPTED";
    public static final String DISCARD_ON_COMPLETE = "DISCARD_ON_COMPLETE";

    public static final String SERVICE_URI_LOCATION = "ServiceURI";

    public static final String WSDL_EPR_PREFIX = "WSDLEPRPrefix";

    public static final String EPR_TO_SERVICE_NAME_MAP = "service.epr.map";
    public static final String NON_BLOCKING_TRANSPORT = "NonBlockingTransport";
    public static final String SERIALIZED_BYTES = "SerializedBytes";

    public static final String CONTENT_TYPE = "CONTENT_TYPE";
    // This property can be used to remove character encode. By default character encoding is enabled in the ESB profile.
    // If this property is set to 'false', the 'CHARACTER_SET_ENCODING' property cannot be used.
    public static final String SET_CHARACTER_ENCODING = "setCharacterEncoding";

    public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
    public static final String CONTENT_TYPE_MULTIPART_RELATED = "multipart/related";
    public static final String CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data";

    public final static String JSON_CONTENT_TYPE = "application/json";

    public static final String HIDDEN_SERVICE_PARAM_NAME = "hiddenService";

    /** An Axis2 message context property indicating a transport send failure */
    public static final String SENDING_FAULT = "SENDING_FAULT";
    /** The message context property name which holds the error code for the last encountered exception */
    public static final String ERROR_CODE = "ERROR_CODE";
    /** The message context property name which holds the error code for the last encountered exception
     * without any protocol state specific alterations*/
    public static final String BASE_ERROR_CODE = "BASE_ERROR_CODE";
    /** The message context property name which holds the http protocol state upon a failure*/
    public static final String PROTOCOL_STATE_ON_FAILURE = "PROTOCOL_STATE_ON_FAILURE";
    /** The MC property name which holds the error message for the last encountered exception */
    public static final String ERROR_MESSAGE = "ERROR_MESSAGE";
    /** The message context property name which holds the error detail (stack trace) for the last encountered exception */
    public static final String ERROR_DETAIL = "ERROR_DETAIL";
    /** The message context property name which holds the exception (if any) for the last encountered exception */
    public static final String ERROR_EXCEPTION = "ERROR_EXCEPTION";
    /** An Axis2 message context property that hols the raw payload when an error occurs while building message */
    public static final String RAW_PAYLOAD = "RAW_PAYLOAD";

    // ********** DO NOT CHANGE THESE UNLESS CORRESPONDING SYNAPSE CONSTANT ARE CHANGED ************

    public static final String REST_URL_POSTFIX = "REST_URL_POSTFIX";
    public static final String SERVICE_PREFIX = "SERVICE_PREFIX";
    public static final String NO_ENTITY_BODY = "NO_ENTITY_BODY";

    public static final String PASS_THROUGH_TRANSPORT_WORKER_POOL =
            "PASS_THROUGH_TRANSPORT_WORKER_POOL";
    protected static final String PASS_THROUGH_SOURCE_CONFIGURATION =
            "PASS_THROUGH_SOURCE_CONFIGURATION";
    public static final String PASS_THROUGH_SOURCE_CONNECTION = "pass-through.Source-Connection";
    protected static final String PASS_THROUGH_SOURCE_REQUEST = "pass-through.Source-Request";
    protected static final String PASS_THROUGH_TARGET_CONFIGURATION = "PASS_THROUGH_TARGET_CONFIGURATION";
    protected static final String PASS_THROUGH_TARGET_CONNECTION = "pass-through.Target-Connection";
    protected static final String PASS_THROUGH_TARGET_RESPONSE = "pass-through.Target-Response";

    public static final String PASS_THROUGH_PIPE = "pass-through.pipe";

    // used to define the default content type as a parameter in the axis2.xml
    public static final String REQUEST_CONTENT_TYPE = "DEFAULT_REQUEST_CONTENT_TYPE";

    // This is a workaround  for  axis2 RestUtils behaviour
    public static final String REST_REQUEST_CONTENT_TYPE = "synapse.internal.rest.contentType";

    public static final String MESSAGE_BUILDER_INVOKED = "message.builder.invoked";

    public static final String TRANSPORT_MESSAGE_HANDLER = "transport.message.handler";

    // This is similar to isDoingREST  - if the request contains a REST (i.e. format=POX | GET | REST) call, then we set this to TRUE
    public static final String INVOKED_REST = "invokedREST";

    // Use this to make PassThroughHttpSender set the Message Formatter's writeTo() preserve boolean value
    public static final String FORMATTER_PRESERVE = "chunkedFormatterPreserve";     
    
    public static final String CLONE_PASS_THROUGH_PIPE_REQUEST = "clone_pass-through.pipe_connected";

    public static final String CONNECTION_LIMIT_EXCEEDS = "CONNECTION_LIMIT_EXCEEDS";

    /**
     * Name of the .mar file
     */
    public final static String SECURITY_MODULE_NAME = "rampart";
    
    public final static String REST_GET_DELETE_INVOKE ="rest_get_delete_invoke";

    public final static String FORCE_POST_PUT_NOBODY ="FORCE_POST_PUT_NOBODY";

    public final static String PASSTROUGH_MESSAGE_LENGTH ="PASSTROUGH_MESSAGE_LENGTH";
    
	public static final String CONF_LOCATION = "conf.location";

    public static final String LOCATION = "Location";
    
	public static final String BUFFERED_INPUT_STREAM = "bufferedInputStream";
	
	//JMX statistic calculation Constants
	public static final String REQ_ARRIVAL_TIME = "REQ_ARRIVAL_TIME";
	public static final String REQ_DEPARTURE_TIME = "REQ_DEPARTURE_TIME";
	public static final String RES_ARRIVAL_TIME = "RES_ARRIVAL_TIME";
	public static final String RES_HEADER_ARRIVAL_TIME = "RES_HEADER_ARRIVAL_TIME";
	public static final String RES_DEPARTURE_TIME = "RES_DEPARTURE_TIME";

    public static final String REQ_FROM_CLIENT_READ_START_TIME = "REQ_FROM_CLIENT_READ_START_TIME";
    public static final String REQ_FROM_CLIENT_READ_END_TIME = "REQ_FROM_CLIENT_READ_END_TIME";
    public static final String REQ_FROM_CLIENT_BODY_READ_START_TIME = "REQ_FROM_CLIENT_BODY_READ_START_TIME";

    public static final String REQ_TO_BACKEND_WRITE_START_TIME = "REQ_TO_BACKEND_WRITE_START_TIME";
    public static final String REQ_TO_BACKEND_WRITE_END_TIME = "REQ_TO_BACKEND_WRITE_END_TIME";

    public static final String RES_FROM_BACKEND_READ_START_TIME = "RES_FROM_BACKEND_READ_START_TIME";
    public static final String RES_FROM_BACKEND_READ_END_TIME = "RES_FROM_BACKEND_READ_END_TIME";

    public static final String RES_TO_CLIENT_WRITE_START_TIME = "RES_TO_CLIENT_WRITE_START_TIME";
    public static final String RES_TO_CLIENT_WRITE_END_TIME = "RES_TO_CLIENT_WRITE_END_TIME";
    public static final String RES_TO_CLIENT_BODY_WRITE_START_TIME = "RES_TO_CLIENT_BODY_WRITE_START_TIME";

    public static final String SERVER_WORKER_INIT_TIME = "SERVER_WORKER_INIT_TIME";

    public static final String SERVER_WORKER_REFERENCE = "SERVER_WORKER_REFERENCE";

    public static final String CLIENT_WORKER_REFERENCE = "CLIENT_WORKER_REFERENCE";
    public static final String MESSAGE_DISCARD_WORKER_REFERENCE = "MESSAGE_DISCARD_WORKER_REFERENCE";
    public static final String THREAD_STATUS_RUNNING = "RUNNING";

    public static final String SERVER_WORKER_START_TIME = "SERVER_WORKER_START_TIME";

    public static final String CLIENT_WORKER_INIT_TIME = "CLIENT_WORKER_INIT_TIME";
    public static final String CLIENT_WORKER_START_TIME = "CLIENT_WORKER_START_TIME";

    public static final String SYNAPSE_PASSTHROUGH_LATENCY_ADVANCE_VIEW = "synapse.passthrough.latency_view.enable_advanced_view";
    public static final String SYNAPSE_PASSTHROUGH_S2SLATENCY_ADVANCE_VIEW = "synapse.passthrough.s2slatency_view.enable_advanced_view";
    public static final String PASSTHROUGH_LATENCY_VIEW = "PassthroughLatencyView";
    public static final String PASSTHROUGH_S2SLATENCY_VIEW = "PassthroughS2SLatencyView";
    public static final String PASSTHOUGH_HTTP_SERVER_WORKER = "PassthroughHttpServerWorker";
    public static final String PASSTHROUGH_MESSAGE_PROCESSOR = "PassThroughMessageProcessor";

    public static final String MESSAGE_OUTPUT_FORMAT = "MESSAGE_OUTPUT_FORMAT";
	
	public static final String FORCE_SOAP_FAULT = "FORCE_SOAP_FAULT";
	
	public static final String FORCE_PASSTHROUGH_BUILDER = "force.passthrough.builder";
	
	public static final String WSDL_GEN_HANDLED = "WSDL_GEN_HANDLED";
	
	public static final String COPY_CONTENT_LENGTH_FROM_INCOMING="COPY_CONTENT_LENGTH_FROM_INCOMING";
	
	public static final String ORGINAL_CONTEN_LENGTH="ORGINAL_CONTEN_LENGTH";

	public static final String WAIT_BUILDER_IN_STREAM_COMPLETE="WAIT_BUILDER_IN_STREAM_COMPLETE"; 
	
	public static final String BUILDER_OUTPUT_STREAM="BUILDER_OUTPUT_STREAM";

    // Enable the SOAP trace facility to PassThrough
    public static final String TRACE_SOAP_MESSAGE = "wso2tracer";

    //if this property is true in response path, it mean that client sent Accept-Encoding=gzip header
    public static final String REQUEST_ACCEPTS_GZIP ="REQUEST_ACCEPTS_GZIP" ;
    
    public static final String HTTP_SC_DESC = "HTTP_SC_DESC";
    
    public static final String RELAY_EARLY_BUILD  ="relay_early_build";

    public static final String HTTP_CONTENT_TYPE = "Content-type";
    public static final String HTTP_CONTENT_LENGTH = "Content-Length";

    // Used to determine the configured proxy profile
    public static final String PROXY_PROFILE_TARGET_HOST = "PROXY_PROFILE_TARGET_HOST";

    public static final String PROXY_BASIC_REALM = "BASIC realm=\"proxy\"";

    public static final String HTTP_PROXY_HOST = "http.proxyHost";
    public static final String HTTP_PROXY_PORT = "http.proxyPort";
    public static final String HTTP_PROXY_USERNAME = "http.proxy.username";
    public static final String HTTP_PROXY_PASSWORD = "http.proxy.password";
    public static final String HTTP_NON_PROXY_HOST = "http.nonProxyHosts";
    public static final String HTTP_ETAG_ENABLED = "HTTP_ETAG";

    public static final String ENABLE_WS_ADDRESSING ="enforceWSAddressing";
    
    public static final String SERVER_WORKER_THREAD_ID = "SERVER_WORKER_THREAD_ID";

    //Http method type constants to be used in synapse
    public static final String HTTP_HEAD = "HEAD";
    public static final String HTTP_GET = "GET";
    public static final String HTTP_POST = "POST";
    public static final String HTTP_DELETE = "DELETE";
    public static final String HTTP_PUT = "PUT";
    public static final String HTTP_OPTIONS = "OPTIONS";
    public static final String HTTP_CONNECT = "CONNECT";
    public static final String HTTP_METHOD = "HTTP_METHOD";

    //Constant to specify the socket timeout
    public static final String HTTP_SOCKET_TIMEOUT = "HTTP_SOCKET_TIMEOUT";

    public static final String ORIGINAL_HTTP_SC = "ORIGINAL_STATUS_CODE";
    public static final String ORIGINAL_HTTP_REASON_PHRASE = "HTTP_REASON_PHRASE";
    public static final String INTERNAL_EXCEPTION_ORIGIN = "_INTERNAL_EXCEPTION_ORIGIN";
    public static final String INTERNAL_ORIGIN_ERROR_HANDLER = "TARGET_ERROR_HANDLER";
    public static final String INTERNAL_TRIGGER_TYPE = "_INTERNAL_TRIGGER_TYPE";
    public static final String INTERNAL_TRIGGER_NAME = "_INTERNAL_TRIGGER_NAME";

    public static final String MESSAGE_SIZE_VALIDATION_SUM = "MESSAGE_SIZE_VALIDATION_SUM";
    public static final String SOURCE_CONNECTION_DROPPED = "SOURCE_CONNECTION_DROPPED";

    /*
     * Denotes application/octet-stream content-type
     */
    public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";

    /*
     * System property to configure verification timeout (iterative verification) in seconds for port.
     */
    public static final String SYSTEMPROP_PORT_CLOSE_VERIFY_TIMEOUT = "synapse.transport.portCloseVerifyTimeout";

    //Validate the bad formed xml message by building the whole xml document.
    public static final String FORCE_XML_MESSAGE_VALIDATION = "force.xml.message.validation";

    //Check for invalid json message by parsing the input message
    public static final String FORCE_JSON_MESSAGE_VALIDATION = "force.json.message.validation";

    //system property to enable/disable correlation logging
    public static final String CORRELATION_LOGS_SYS_PROPERTY = "enableCorrelationLogs";
    //correlation logger name in log4J properties
    public static final String CORRELATION_LOGGER = "correlation";
    //default header that carries the correlation ID. Header name is configurable at passthru-http.properties
    public static final String CORRELATION_DEFAULT_HEADER = "activityid";
    public static final String TRANSPORT_LATENCY_LOGGER = "transport-latency";
    public static final String TRANSPORT_IN_URL = "TransportInURL";

    /**
     * Transaction replay configuration properties
     */

    // Configuration key to enable or disable replay transactions in pass-through transport
    public static final String REPLAY_TXN_ENABLED_KEY = "pass.through.transport.enableReplayTransaction";
    // Configuration key for frequency of logging dropped replay messages when the buffer overflows
    public static final String REPLAY_LOG_DROP_FREQUENCY_KEY = "pass.through.transport.replay.buffer.log.drop.frequency";
    // Configuration key defining max size of the replay transaction buffer queue
    public static final String REPLAY_MAX_BUFFER_SIZE_KEY = "pass.through.transport.replay.transaction.max.buffer.size";
    // Configuration key for polling interval (in milliseconds) for replay transaction buffer thread
    public static final String REPLAY_BUFFER_POLL_INTERVAL_MS_KEY = "pass.through.transport.replay.transaction.buffer.poll.interval.ms";
    // Configuration key specifying the fully qualified class name of the ReplayDataWriter implementation
    public static final String REPLAY_TRANSACTION_WRITER_CLASS_KEY = "pass.through.transport.replay.transaction.writer.class";
    // Core number of threads to keep in the pool consistently during idle periods
    public static final String REPLAY_WORKER_CORE_POOL_SIZE_KEY = "pass.through.transport.replay.worker.core.pool.size";
    // Maximum number of threads allowed in the pool to handle peak loads
    public static final String REPLAY_WORKER_MAX_POOL_SIZE_KEY = "pass.through.transport.replay.worker.max.pool.size";
    // Idle timeout in milliseconds after which threads above core size are terminated
    public static final String REPLAY_WORKER_KEEP_ALIVE_TIME_MS_KEY = "pass.through.transport.replay.worker.keep.alive.time.ms";
    // Allowed HTTP methods for replay writes.
    // Arrays.asList creates a fixed-size list of elements,
    // HashSet provides fast O(1) lookup for membership checks,
    // Collections.unmodifiableSet wraps to ensure immutability for thread safety and consistency,
    // this combination balances initialization simplicity, read performance, and memory efficiency.
    public static final Set<String> ALLOWED_WRITE_METHODS =
            Collections.unmodifiableSet(new HashSet<>(Arrays.asList("POST", "PUT", "PATCH", "DELETE")));
    public static final String CHUNK_ORDER_PROPERTY = "CHUNK_ORDER";
}
