/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.camel.component.telegram;

import java.util.Collections;
import java.util.List;

import org.apache.camel.Component;
import org.apache.camel.Consumer;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.component.telegram.model.Update;
import org.apache.camel.component.webhook.WebhookCapableEndpoint;
import org.apache.camel.component.webhook.WebhookConfiguration;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.support.ScheduledPollEndpoint;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.camel.component.telegram.util.TelegramMessageHelper.populateExchange;

/**
 * The telegram component provides access to the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.
 */
@UriEndpoint(firstVersion = "2.18.0", scheme = "telegram", title = "Telegram", syntax = "telegram:type", label = "chat")
public class TelegramEndpoint extends ScheduledPollEndpoint implements WebhookCapableEndpoint {
    private static final Logger LOG = LoggerFactory.getLogger(TelegramEndpoint.class);

    @UriParam
    private TelegramConfiguration configuration;

    private WebhookConfiguration webhookConfiguration;

    public TelegramEndpoint(String endpointUri, Component component, TelegramConfiguration configuration) {
        super(endpointUri, component);
        this.configuration = configuration;
        // setup the proxy setting here
        if (ObjectHelper.isNotEmpty(configuration.getProxyHost()) && ObjectHelper.isNotEmpty(configuration.getProxyPort())) {
            LOG.debug("Setup http proxy host:{} port:{} for TelegramService", configuration.getProxyHost(), configuration.getProxyPort());
            TelegramServiceProvider.get().getService().setHttpProxy(configuration.getProxyHost(), configuration.getProxyPort());
        }
    }

    @Override
    public Producer createProducer() throws Exception {
        return new TelegramProducer(this);
    }

    @Override
    public Consumer createConsumer(Processor processor) throws Exception {
        TelegramConsumer consumer = new TelegramConsumer(this, processor);
        configureConsumer(consumer);
        return consumer;
    }

    public Exchange createExchange(Update update) {
        Exchange exchange = super.createExchange();
        populateExchange(exchange, update);
        return exchange;
    }

    @Override
    public Processor createWebhookHandler(Processor next) {
        return new TelegramWebhookProcessor(next);
    }

    @Override
    public void registerWebhook() throws Exception {
        TelegramService service = TelegramServiceProvider.get().getService();
        if (!service.setWebhook(configuration.getAuthorizationToken(), webhookConfiguration.computeFullExternalUrl())) {
            throw new RuntimeCamelException("The Telegram API refused to register a webhook");
        }
    }

    @Override
    public void unregisterWebhook() throws Exception {
        TelegramService service = TelegramServiceProvider.get().getService();
        if (!service.removeWebhook(configuration.getAuthorizationToken())) {
            throw new RuntimeCamelException("The Telegram API refused to unregister the webhook");
        }
    }

    public WebhookConfiguration getWebhookConfiguration() {
        return webhookConfiguration;
    }

    @Override
    public void setWebhookConfiguration(WebhookConfiguration webhookConfiguration) {
        this.webhookConfiguration = webhookConfiguration;
    }

    @Override
    public List<String> getWebhookMethods() {
        return Collections.singletonList("POST");
    }

    public TelegramConfiguration getConfiguration() {
        return configuration;
    }

    public void setConfiguration(TelegramConfiguration configuration) {
        this.configuration = configuration;
    }

}
