/*
 * Copyright 2015 the original author or authors.
 *
 * 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.springframework.cloud.sleuth.stream;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.sleuth.Sampler;
import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.cloud.sleuth.event.ClientReceivedEvent;
import org.springframework.cloud.sleuth.event.ClientSentEvent;
import org.springframework.cloud.sleuth.event.ServerReceivedEvent;
import org.springframework.cloud.sleuth.event.ServerSentEvent;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.cloud.sleuth.stream.StreamSpanListenerTests.TestConfiguration;
import org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration;
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.Message;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;

/**
 * @author Dave Syer
 *
 */
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class StreamSpanListenerTests {

	@Autowired Tracer tracer;
	@Autowired ApplicationContext application;
	@Autowired ZipkinTestConfiguration test;
	@Autowired StreamSpanListener listener;
	@Autowired CounterService counterService;

	@PostConstruct
	public void init() {
		this.test.spans.clear();
	}

	@Test
	public void acquireAndRelease() {
		Span context = this.tracer.startTrace("foo");
		this.tracer.close(context);
		assertEquals(1, this.test.spans.size());
	}

	@Test
	public void rpcAnnotations() {
		Span parent = Span.builder().traceId(1L).name("parent").remote(true)
				.build();
		Span context = this.tracer.joinTrace("child", parent);
		this.application.publishEvent(new ClientSentEvent(this, context));
		this.application
				.publishEvent(new ServerReceivedEvent(this, parent, context));
		this.application
				.publishEvent(new ServerSentEvent(this, parent, context));
		this.application.publishEvent(new ClientReceivedEvent(this, context));
		this.tracer.close(context);
		assertEquals(2, this.test.spans.size());
	}

	@Test
	public void nullSpanName() {
		Span context = this.tracer.startTrace(null, null);
		this.application.publishEvent(new ClientSentEvent(this, context));
		this.tracer.close(context);
		assertEquals(1, this.test.spans.size());
		this.listener.poll();
		assertEquals(0, this.test.spans.size());
	}

	@Test
	public void shouldIncreaseNumberOfAcceptedSpans() {
		Span context = this.tracer.startTrace("foo");
		this.tracer.close(context);
		this.listener.poll();

		verify(this.counterService, atLeastOnce()).increment(anyString());
	}

	@Configuration
	@Import({ ZipkinTestConfiguration.class, SleuthStreamAutoConfiguration.class,
			TestSupportBinderAutoConfiguration.class, ChannelBindingAutoConfiguration.class,
			TraceAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
	protected static class TestConfiguration {}

	@Configuration
	@MessageEndpoint
	protected static class ZipkinTestConfiguration {

		private List<Span> spans = new ArrayList<>();

		@Autowired
		StreamSpanListener listener;

		@ServiceActivator(inputChannel=SleuthSource.OUTPUT)
		public void handle(Message<?> msg) {
		}

		@Bean
		public Sampler defaultSampler() {
			return new AlwaysSampler();
		}

		@Bean CounterService counterService() {
			return Mockito.mock(CounterService.class);
		}

		@PostConstruct
		public void init() {
			this.listener.setQueue(this.spans);
		}

	}

}

@@ -660,16 +660,289 @@
 tream;%0A%0A
+import static org.junit.Assert.assertEquals;%0Aimport static org.mockito.Matchers.anyString;%0Aimport static org.mockito.Mockito.atLeastOnce;%0Aimport static org.mockito.Mockito.verify;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0A%0Aimport javax.annotation.PostConstruct;%0A%0A
 import o
@@ -952,24 +952,24 @@
 junit.Test;%0A
-
 import org.j
@@ -2576,280 +2576,8 @@
 r;%0A%0A
-import javax.annotation.PostConstruct;%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0A%0Aimport static org.junit.Assert.assertEquals;%0Aimport static org.mockito.Matchers.anyString;%0Aimport static org.mockito.Mockito.atLeastOnce;%0Aimport static org.mockito.Mockito.verify;%0A%0A
 /**%0A
@@ -3789,39 +3789,36 @@
 Name() %7B%0A%09%09Span 
-context
+span
  = this.tracer.s
@@ -3831,14 +3831,8 @@
 ace(
-null, 
 null
@@ -3884,39 +3884,36 @@
 SentEvent(this, 
-context
+span
 ));%0A%09%09this.trace
@@ -3912,39 +3912,36 @@
 is.tracer.close(
-context
+span
 );%0A%09%09assertEqual

Fix test with wrong asdsumption about null sampler