package com.google.cloud.opentelemetry.trace;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.google.auth.Credentials;
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.ServiceOptions;
import io.opentelemetry.common.AttributeValue;
import java.util.Collections;
import java.util.Date;
import java.time.Duration;
import java.util.Map;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link TraceConfiguration}. */
@RunWith(JUnit4.class)
public class TraceConfigurationTest {

    private static final Credentials FAKE_CREDENTIALS = GoogleCredentials.newBuilder()
            .setAccessToken(new AccessToken("fake", new Date(100))).build();
    private static final String PROJECT_ID = "project";
    private static final Duration ONE_MINUTE = Duration.ofSeconds(60, 0);
    private static final Duration NEG_ONE_MINUTE = Duration.ofSeconds(-60, 0);

    @Rule
    public final ExpectedException thrown = ExpectedException.none();

    @Test
    public void defaultConfiguration() {
        TraceConfiguration configuration;
        try {
            configuration = TraceConfiguration.builder().build();
        } catch (Exception e) {
            // Some test hosts may not have cloud project ID set up.
            configuration = TraceConfiguration.builder().setProjectId("test").build();
        }
        assertNull(configuration.getCredentials());
        assertNotNull(configuration.getProjectId());
        assertNull(configuration.getTraceServiceStub());
        assertTrue(configuration.getFixedAttributes().isEmpty());
        assertEquals(configuration.getDeadline(), TraceConfiguration.DEFAULT_DEADLINE);
    }

    @Test
    public void updateAll() {
        Map<String, AttributeValue> attributes = Collections.singletonMap("key",
                AttributeValue.stringAttributeValue("val"));
        TraceConfiguration configuration = TraceConfiguration.builder().setCredentials(FAKE_CREDENTIALS)
                .setProjectId(PROJECT_ID).setFixedAttributes(attributes).setDeadline(ONE_MINUTE).build();
        assertEquals(configuration.getCredentials(), FAKE_CREDENTIALS);
        assertEquals(configuration.getProjectId(), PROJECT_ID);
        assertEquals(configuration.getFixedAttributes(), attributes);
        assertEquals(configuration.getDeadline(), ONE_MINUTE);
    }

    @Test
    public void disallowNullProjectId() {
        TraceConfiguration.Builder builder = TraceConfiguration.builder();
        thrown.expect(NullPointerException.class);
        builder.setProjectId(null);
    }

    @Test
    public void disallowEmptyProjectId() {
        TraceConfiguration.Builder builder = TraceConfiguration.builder();
        builder.setProjectId("");
        thrown.expect(IllegalArgumentException.class);
        builder.build();
    }

    @Test
    public void allowToUseDefaultProjectId() {
        String defaultProjectId = ServiceOptions.getDefaultProjectId();
        if (defaultProjectId != null) {
            TraceConfiguration configuration = TraceConfiguration.builder().build();
            assertEquals(configuration.getProjectId(), defaultProjectId);
        }
    }

    @Test
    public void disallowNullFixedAttributes() {
        TraceConfiguration.Builder builder = TraceConfiguration.builder().setProjectId("test");
        thrown.expect(NullPointerException.class);
        builder.setFixedAttributes(null);
    }

    @Test
    public void disallowNullFixedAttributeKey() {
        TraceConfiguration.Builder builder = TraceConfiguration.builder().setProjectId("test");
        Map<String, AttributeValue> attributes = Collections.singletonMap(null,
                AttributeValue.stringAttributeValue("val"));
        builder.setFixedAttributes(attributes);
        thrown.expect(NullPointerException.class);
        builder.build();
    }

    @Test
    public void disallowNullFixedAttributeValue() {
        TraceConfiguration.Builder builder = TraceConfiguration.builder().setProjectId("test");
        Map<String, AttributeValue> attributes = Collections.singletonMap("key", null);
        builder.setFixedAttributes(attributes);
        thrown.expect(NullPointerException.class);
        builder.build();
    }

    @Test
    public void disallowZeroDuration() {
        TraceConfiguration.Builder builder = TraceConfiguration.builder().setProjectId("test");
        builder.setDeadline(TraceConfiguration.Builder.ZERO);
        thrown.expect(IllegalArgumentException.class);
        builder.build();
    }

    @Test
    public void disallowNegativeDuration() {
        TraceConfiguration.Builder builder = TraceConfiguration.builder().setProjectId("test");
        builder.setDeadline(NEG_ONE_MINUTE);
        thrown.expect(IllegalArgumentException.class);
        builder.build();
    }

}

@@ -216,16 +216,61 @@
 ertTrue;
+%0Aimport static org.junit.Assert.assertThrows;
 %0A%0Aimport
@@ -584,31 +584,8 @@
 ap;%0A
-import org.junit.Rule;%0A
 impo
@@ -1202,89 +1202,8 @@
 );%0A%0A
-    @Rule%0A    public final ExpectedException thrown = ExpectedException.none();%0A%0A
     
@@ -2692,37 +2692,36 @@
 ();%0A        
-thrown.expect
+assertThrows
 (NullPointer
@@ -2731,34 +2731,31 @@
 eption.class
-);%0A       
+, () -%3E
  builder.set
@@ -2765,24 +2765,25 @@
 jectId(null)
+)
 ;%0A    %7D%0A%0A   
@@ -2945,37 +2945,36 @@
 %22);%0A        
-thrown.expect
+assertThrows
 (IllegalArgu
@@ -2988,34 +2988,31 @@
 eption.class
-);%0A       
+, () -%3E
  builder.bui
@@ -3007,32 +3007,33 @@
  builder.build()
+)
 ;%0A    %7D%0A%0A    @Te
@@ -3528,37 +3528,36 @@
 %22);%0A        
-thrown.expect
+assertThrows
 (NullPointer
@@ -3567,34 +3567,31 @@
 eption.class
-);%0A       
+, () -%3E
  builder.set
@@ -3607,24 +3607,25 @@
 ibutes(null)
+)
 ;%0A    %7D%0A%0A   
@@ -3970,37 +3970,36 @@
 s);%0A        
-thrown.expect
+assertThrows
 (NullPointer
@@ -4009,34 +4009,31 @@
 eption.class
-);%0A       
+, () -%3E
  builder.bui
@@ -4028,32 +4028,33 @@
  builder.build()
+)
 ;%0A    %7D%0A%0A    @Te
@@ -4348,29 +4348,28 @@
         
-thrown.expect
+assertThrows
 (NullPoi
@@ -4383,34 +4383,31 @@
 eption.class
-);%0A       
+, () -%3E
  builder.bui
@@ -4402,32 +4402,33 @@
  builder.build()
+)
 ;%0A    %7D%0A%0A    @Te
@@ -4633,37 +4633,36 @@
 O);%0A        
-thrown.expect
+assertThrows
 (IllegalArgu
@@ -4676,34 +4676,31 @@
 eption.class
-);%0A       
+, () -%3E
  builder.bui
@@ -4695,32 +4695,33 @@
  builder.build()
+)
 ;%0A    %7D%0A%0A    @Te
@@ -4921,21 +4921,20 @@
     
-thrown.expect
+assertThrows
 (Ill
@@ -4960,26 +4960,23 @@
 on.class
-);%0A       
+, () -%3E
  builder
@@ -4979,23 +4979,24 @@
 lder.build()
+)
 ;%0A    %7D%0A%0A%7D%0A

update unit tests to user AssertThrows over deprecated junit rule