/*
 * Copyright (c) 2015-2026, 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.wso2.carbon.event.stream.core;

import org.wso2.carbon.databridge.commons.Event;
import org.wso2.carbon.databridge.commons.StreamDefinition;
import org.wso2.carbon.event.stream.core.exception.EventStreamConfigurationException;
import org.wso2.carbon.event.stream.core.exception.EventStreamException;
import org.wso2.carbon.event.stream.core.internal.util.EventStreamConstants;

import java.util.List;

public interface EventStreamService {


    /**
     * @param name
     * @param version
     * @return
     */
    public StreamDefinition getStreamDefinition(String name, String version)
            throws EventStreamConfigurationException;

    /**
     * @param streamId
     * @return
     */
    public StreamDefinition getStreamDefinition(String streamId)
            throws EventStreamConfigurationException;

    public EventStreamConfiguration getEventStreamConfiguration(String streamId);

    /**
     * @return
     * @throws EventStreamConfigurationException
     */
    public List<StreamDefinition> getAllStreamDefinitions()
            throws EventStreamConfigurationException;


    public List<EventStreamConfiguration> getAllEventStreamConfigurations()
            throws EventStreamConfigurationException;
    /**
     * @param streamDefinition
     * @throws EventStreamConfigurationException
     */
    public void addEventStreamDefinition(StreamDefinition streamDefinition) throws
            EventStreamConfigurationException;

    /**
     * @param streamName
     * @param streamVersion
     * @throws EventStreamConfigurationException
     */
    public void removeEventStreamDefinition(String streamName, String streamVersion)
            throws EventStreamConfigurationException;

    /**
     * @return
     * @throws EventStreamConfigurationException
     */
    public List<String> getStreamIds() throws EventStreamConfigurationException;


    public String generateSampleEvent(String streamId, String eventType)
            throws EventStreamConfigurationException;

    public void subscribe(SiddhiEventConsumer siddhiEventConsumer) throws EventStreamConfigurationException;

    public void subscribe(EventProducer eventProducer) throws EventStreamConfigurationException;

    public void subscribe(WSO2EventConsumer wso2EventConsumer) throws EventStreamConfigurationException;

    public void subscribe(WSO2EventListConsumer wso2EventListConsumer) throws EventStreamConfigurationException;

    public void unsubscribe(SiddhiEventConsumer siddhiEventConsumer);

    public void unsubscribe(EventProducer eventProducer);

    public void unsubscribe(WSO2EventConsumer wso2EventConsumer);

    public void unsubscribe(WSO2EventListConsumer wso2EventConsumer);

    public void publish(Event event);

    /**
     * Publishes an event to the stream using the error-propagating path. Every subscribed consumer
     * is invoked regardless of whether a previous consumer failed. If exactly one consumer fails, a
     * {@link org.wso2.carbon.event.stream.core.exception.ConsumerFailureException} is thrown. If
     * multiple consumers fail, an
     * {@link org.wso2.carbon.event.stream.core.exception.AggregatedConsumerFailureException} is
     * thrown; individual failures are accessible via
     * {@link org.wso2.carbon.event.stream.core.exception.AggregatedConsumerFailureException#getFailures()}.
     *
     * @param event Event to publish.
     * @throws org.wso2.carbon.event.stream.core.exception.EventStreamException If one or more
     *         consumers failed to process the event.
     */
    public default void publishAndNotifyErrors(Event event) throws EventStreamException {

        throw new EventStreamException(
                EventStreamConstants.ErrorMessage.SERVICE_PUBLISH_NOT_IMPLEMENTED.getCode(),
                EventStreamConstants.ErrorMessage.SERVICE_PUBLISH_NOT_IMPLEMENTED.getMessage());
    }

    /**
     * Add the Event Stream Configuration.
     *
     * @param eventStreamConfiguration Event Stream Configuration, as a configuration object.
     * @throws EventStreamConfigurationException
     */
    public default void addEventStreamConfig(EventStreamConfiguration eventStreamConfiguration)
            throws EventStreamConfigurationException {
    }

    /**
     * Removes every event stream configuration and event junction held in memory for the given tenant.
     * Intended to be invoked when a tenant is unloaded — after its event publishers have been removed —
     * so that per-tenant stream state does not accumulate for every tenant ever loaded during the
     * server's lifetime.
     *
     * @param tenantId Tenant ID.
     */
    public default void removeEventStreamConfigurations(int tenantId) {

    }

}
