/*******************************************************************************
 * Copyright (c) 2015 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package com.openshift.restclient;

import static com.openshift.internal.restclient.IntegrationTestHelper.cleanUpResource;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.openshift.internal.restclient.IntegrationTestHelper;
import com.openshift.restclient.IOpenShiftWatchListener.ChangeType;
import com.openshift.restclient.model.IResource;
import com.openshift.restclient.model.IService;

public class WatchClientIntegrationTest {

	private static final Logger LOG = LoggerFactory.getLogger(WatchClientIntegrationTest.class);

	private IntegrationTestHelper helper = new IntegrationTestHelper();
	private IClient client;
	private IResource project;
	public static final String [] KINDS = new String[] {
			ResourceKind.BUILD_CONFIG, 
			ResourceKind.DEPLOYMENT_CONFIG, 
			ResourceKind.SERVICE, 
			ResourceKind.POD,
			ResourceKind.REPLICATION_CONTROLLER, 
			ResourceKind.BUILD, 
			ResourceKind.IMAGE_STREAM, 
			ResourceKind.ROUTE
	};

	private ExecutorService service;
	private boolean isError;

	@Before
	public void setup() {
		service = Executors.newSingleThreadScheduledExecutor();
		client = helper.createClientForBasicAuth();
		IResource projRequest = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, helper.generateNamespace());
		project = client.create(projRequest);
	}
	
	@After
	public void teardown() {
		cleanUpResource(client, project);
		service.shutdownNow();
	}
	
	@SuppressWarnings("rawtypes")
	@Test(timeout=60000)
	public void test() throws Exception{
		List results = new ArrayList();
		CountDownLatch latch = new CountDownLatch(KINDS.length);
		IOpenShiftWatchListener listener = new IOpenShiftWatchListener() {

			@SuppressWarnings("unchecked")
			@Override
			public void received(IResource resource, ChangeType change) {
				results.add(change);
			}
			
			@Override
			public void connected(List<IResource> resources) {
				latch.countDown();
			}

			@Override
			public void disconnected() {
				latch.countDown();
			}

			@Override
			public void error(Throwable err) {
				latch.countDown();
				isError = true;
				LOG.error("",err);
			}
		};
		
		IWatcher watcher = null;
		try {
			watcher = client.watch(project.getName(), listener, KINDS);
			latch.await();
			assertFalse("Expected connection without error",isError);
			IService service = client.getResourceFactory().stub(ResourceKind.SERVICE,"hello-world", project.getName());
			service.addPort(8080,8080);
			service = client.create(service);
			service.addLabel("foo", "bar");
			service = client.update(service);
			client.delete(service);
			assertArrayEquals(new ChangeType[] {ChangeType.ADDED, ChangeType.MODIFIED, ChangeType.DELETED}, results.toArray());
			assertEquals(0, latch.getCount());
		}finally {
			if(watcher != null) {
				watcher.stop();
			}
		}
	}

}
