package com.commafeed.backend.favicon;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;

import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.HttpGetter;
import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.model.Feed;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Channel;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtube.model.Thumbnail;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
@Singleton
public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {

	private final HttpGetter getter;
	private final CommaFeedConfiguration config;

	@Override
	public Favicon fetch(Feed feed) {
		String url = feed.getUrl();

		if (!url.toLowerCase().contains("youtube.com/feeds/videos.xml")) {
			return null;
		}

		String googleAuthKey = config.getApplicationSettings().getGoogleAuthKey();
		if (googleAuthKey == null) {
			log.debug("no google auth key configured");
			return null;
		}

		byte[] bytes = null;
		String contentType = null;
		try {
			List<NameValuePair> params = URLEncodedUtils.parse(url.substring(url.indexOf("?") + 1), StandardCharsets.UTF_8);
			Optional<NameValuePair> userId = params.stream().filter(nvp -> nvp.getName().equalsIgnoreCase("user")).findFirst();
			Optional<NameValuePair> channelId = params.stream().filter(nvp -> nvp.getName().equalsIgnoreCase("channel_id")).findFirst();
			if (!userId.isPresent() && !channelId.isPresent()) {
				return null;
			}

			YouTube youtube = new YouTube.Builder(new NetHttpTransport(), JacksonFactory.getDefaultInstance(),
					new HttpRequestInitializer() {
						@Override
						public void initialize(HttpRequest request) throws IOException {
						}
					}).setApplicationName("CommaFeed").build();

			YouTube.Channels.List list = youtube.channels().list("snippet");
			list.setKey(googleAuthKey);
			if (userId.isPresent()) {
				list.setForUsername(userId.get().getValue());
			} else {
				list.setId(channelId.get().getValue());
			}

			log.debug("contacting youtube api");
			ChannelListResponse response = list.execute();
			if (response.getItems().isEmpty()) {
				log.debug("youtube api returned no items");
				return null;
			}

			Channel channel = response.getItems().get(0);
			Thumbnail thumbnail = channel.getSnippet().getThumbnails().getDefault();

			log.debug("fetching favicon");
			HttpResult iconResult = getter.getBinary(thumbnail.getUrl(), TIMEOUT);
			bytes = iconResult.getContent();
			contentType = iconResult.getContentType();
		} catch (Exception e) {
			log.debug("Failed to retrieve YouTube icon", e);
		}

		if (!isValidIconResponse(bytes, contentType)) {
			return null;
		}
		return new Favicon(bytes, contentType);
	}
}