/*
 * Copyright 2017 The OpenTracing 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 io.opentracing.contrib.tracerresolver;

import io.opentracing.Tracer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class TracerResolverTest {
    private static final File TRACERRESOLVER_SERVICE_FILE =
            new File("target/test-classes/META-INF/services/" + TracerResolver.class.getName());
    private static final File TRACER_SERVICE_FILE =
            new File("target/test-classes/META-INF/services/" + Tracer.class.getName());

    @After
    public void cleanServiceFiles() throws IOException {
        if (TRACERRESOLVER_SERVICE_FILE.isFile()) TRACERRESOLVER_SERVICE_FILE.delete();
        if (TRACER_SERVICE_FILE.isFile()) TRACER_SERVICE_FILE.delete();
    }

    @Before
    @After
    public void resetTracerResolver() {
        TracerResolver.reload();
    }

    @Test
    public void testNothingRegistered() throws IOException {
        assertThat(TracerResolver.resolveTracer(), is(nullValue()));
    }

    @Test
    public void testResolveTracer() throws IOException {
        writeServiceFile(TRACERRESOLVER_SERVICE_FILE, Mocks.MockTracerResolver.class.getName());
        assertThat(TracerResolver.resolveTracer(), is(instanceOf(Mocks.ResolvedTracer.class)));
    }

    @Test
    public void testResolveFallback() throws IOException {
        writeServiceFile(TRACER_SERVICE_FILE, Mocks.FallbackTracer.class.getName());
        assertThat(TracerResolver.resolveTracer(), is(instanceOf(Mocks.FallbackTracer.class)));
    }

    @Test
    public void testResolverBeatsFallback() throws IOException {
        writeServiceFile(TRACER_SERVICE_FILE, Mocks.FallbackTracer.class.getName());
        writeServiceFile(TRACERRESOLVER_SERVICE_FILE, Mocks.MockTracerResolver.class.getName());
        assertThat(TracerResolver.resolveTracer(), is(instanceOf(Mocks.ResolvedTracer.class)));
    }

    @Test
    public void testFallbackWhenResolvingNull() throws IOException {
        writeServiceFile(TRACER_SERVICE_FILE, Mocks.FallbackTracer.class.getName());
        writeServiceFile(TRACERRESOLVER_SERVICE_FILE, Mocks.NullTracerResolver.class.getName());
        assertThat(TracerResolver.resolveTracer(), is(instanceOf(Mocks.FallbackTracer.class)));
    }

    @Test
    public void testResolvingNullWithoutFallback() throws IOException {
        writeServiceFile(TRACERRESOLVER_SERVICE_FILE, Mocks.NullTracerResolver.class.getName());
        assertThat(TracerResolver.resolveTracer(), is(nullValue()));
    }

    private static void writeServiceFile(File serviceFile, String content) throws IOException {
        serviceFile.getParentFile().mkdirs();
        if (serviceFile.isFile()) serviceFile.delete();
        PrintWriter writer = new PrintWriter(new FileWriter(serviceFile));
        try {
            writer.println(content);
        } finally {
            writer.close();
        }
    }

}

@@ -1020,198 +1020,22 @@
 ile 
-TRACERRESOLVER_SERVICE_FILE =%0A            new File(%22target/test-classes/META-INF/services/%22 + TracerResolver.class.getName());%0A    private static final File TRACER_SERVICE_FILE =%0A           
+SERVICES_DIR =
  new
@@ -1084,33 +1084,8 @@
 es/%22
- + Tracer.class.getName()
 );%0A%0A
@@ -1164,149 +1164,127 @@
     
-if (TRACERRESOLVER_SERVICE_FILE.isFile()) TRACERRESOLVER_SERVICE_FILE.delete();%0A        if (TRACER_SERVICE_FILE.isFile()) TRACER_SERVICE_FILE
+new File(SERVICES_DIR, TracerResolver.class.getName()).delete();%0A        new File(SERVICES_DIR, Tracer.class.getName())
 .del
@@ -1644,34 +1644,27 @@
 le(T
-RACERRESOLVER_SERVICE_FILE
+racerResolver.class
 , Mo
@@ -1687,34 +1687,24 @@
 solver.class
-.getName()
 );%0A        a
@@ -1892,34 +1892,27 @@
 ceFile(T
-RACER_SERVICE_FILE
+racer.class
 , Mocks.
@@ -1927,34 +1927,24 @@
 Tracer.class
-.getName()
 );%0A        a
@@ -2138,34 +2138,27 @@
 ceFile(T
-RACER_SERVICE_FILE
+racer.class
 , Mocks.
@@ -2173,34 +2173,24 @@
 Tracer.class
-.getName()
 );%0A        w
@@ -2210,34 +2210,27 @@
 le(T
-RACERRESOLVER_SERVICE_FILE
+racerResolver.class
 , Mo
@@ -2253,34 +2253,24 @@
 solver.class
-.getName()
 );%0A        a
@@ -2472,26 +2472,19 @@
 le(T
-RACER_SERVICE_FILE
+racer.class
 , Mo
@@ -2503,34 +2503,24 @@
 Tracer.class
-.getName()
 );%0A        w
@@ -2540,34 +2540,27 @@
 le(T
-RACERRESOLVER_SERVICE_FILE
+racerResolver.class
 , Mo
@@ -2583,34 +2583,24 @@
 solver.class
-.getName()
 );%0A        a
@@ -2805,34 +2805,27 @@
 le(T
-RACERRESOLVER_SERVICE_FILE
+racerResolver.class
 , Mo
@@ -2852,26 +2852,16 @@
 er.class
-.getName()
 );%0A     
@@ -2949,16 +2949,22 @@
 e static
+ %3CSVC%3E
  void wr
@@ -2982,106 +2982,184 @@
 ile(
-File serviceFile, String content) throws IOException %7B%0A        serviceFile.getParentFile().mkdirs(
+Class%3CSVC%3E service, Class%3C? extends SVC%3E implementation) throws IOException %7B%0A        SERVICES_DIR.mkdirs();%0A        File serviceFile = new File(SERVICES_DIR, service.getName()
 );%0A 
@@ -3333,15 +3333,32 @@
 tln(
-content
+implementation.getName()
 );%0A 

Test simplification, less File, more Class.