// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.android;

import static com.google.common.truth.Truth.assertThat;

import com.google.devtools.build.android.Converters.ExistingPathConverter;
import com.google.devtools.build.android.Converters.ExistingPathStringDictionaryConverter;
import com.google.devtools.build.android.Converters.PathConverter;
import com.google.devtools.build.android.Converters.PathListConverter;
import com.google.devtools.build.android.Converters.StringDictionaryConverter;
import com.google.devtools.common.options.OptionsParsingException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for {@link Converters}.
 */
@RunWith(JUnit4.class)
public final class ConvertersTest {

  @Rule public final TemporaryFolder tmp = new TemporaryFolder();

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

  @Test
  public void testPathConverter_empty() throws Exception {
    PathConverter converter = new PathConverter();
    Path result = converter.convert("");
    assertThat((Object) result).isEqualTo(Paths.get(""));
  }

  @Test
  public void testPathConverter_invalid() throws Exception {
    String arg = "\u0000";
    PathConverter converter = new PathConverter();
    expected.expect(OptionsParsingException.class);
    expected.expectMessage(String.format("%s is not a valid path:", arg));
    converter.convert(arg);
  }

  @Test
  public void testPathConverter_valid() throws Exception {
    PathConverter converter = new PathConverter();
    Path result = converter.convert("test_file");
    assertThat((Object) result).isEqualTo(Paths.get("test_file"));
  }

  @Test
  public void testExistingPathConverter_nonExisting() throws Exception {
    String arg = "test_file";
    ExistingPathConverter converter = new ExistingPathConverter();
    expected.expect(OptionsParsingException.class);
    expected.expectMessage(String.format("%s is not a valid path: it does not exist.", arg));
    converter.convert(arg);
  }

  @Test
  public void testExistingPathConverter_existing() throws Exception {
    Path testFile = tmp.newFile("test_file").toPath();
    ExistingPathConverter converter = new ExistingPathConverter();
    Path result = converter.convert(testFile.toString());
    assertThat((Object) result).isEqualTo(testFile);
  }

  @Test
  public void testPathListConverter() throws Exception {
    PathListConverter converter = new PathListConverter();
    assertThat(converter.convert("foo:bar::baz:"))
        .containsAllOf(Paths.get("foo"), Paths.get("bar"), Paths.get("baz"))
        .inOrder();
  }

  @Test
  public void testStringDictionaryConverter_emptyEntry() throws Exception {
    StringDictionaryConverter converter = new StringDictionaryConverter();
    expected.expect(OptionsParsingException.class);
    expected.expectMessage("Dictionary entry [] does not contain both a key and a value.");
    converter.convert("foo:bar,,baz:bar");
  }

  @Test
  public void testStringDictionaryConverter_missingKeyOrValue() throws Exception {
    String badEntry = "foo";
    StringDictionaryConverter converter = new StringDictionaryConverter();
    expected.expect(OptionsParsingException.class);
    expected.expectMessage(String.format(
        "Dictionary entry [%s] does not contain both a key and a value.", badEntry));
    converter.convert(badEntry);
  }

  @Test
  public void testStringDictionaryConverter_extraFields() throws Exception {
    String badEntry = "foo:bar:baz";
    StringDictionaryConverter converter = new StringDictionaryConverter();
    expected.expect(OptionsParsingException.class);
    expected.expectMessage(String.format(
        "Dictionary entry [%s] contains too many fields.", badEntry));
    converter.convert(badEntry);
  }

  @Test
  public void testStringDictionaryConverter_duplicateKey() throws Exception {
    String key = "foo";
    String arg = String.format("%s:%s,%s:%s", key, "bar", key, "baz");
    StringDictionaryConverter converter = new StringDictionaryConverter();
    expected.expect(OptionsParsingException.class);
    expected.expectMessage(String.format(
        "Dictionary already contains the key [%s].", key));
    converter.convert(arg);
  }

  @Test
  public void testStringDictionaryConverter() throws Exception {
    StringDictionaryConverter converter = new StringDictionaryConverter();
    Map<String, String> result = converter.convert("foo:bar,baz:messy\\:stri\\,ng");
    assertThat(result).containsExactly("foo", "bar", "baz", "messy:stri,ng");
  }

  @Test
  public void testExistingPathStringDictionaryConverter() throws Exception {
    Path existingFile = tmp.newFile("existing").toPath();
    ExistingPathStringDictionaryConverter converter = new ExistingPathStringDictionaryConverter();
    Map<Path, String> result =
        converter
            // On Windows, the path starts like C:\foo\bar\..., we need to escape the colon.
            .convert(String.format("%s:string", existingFile.toString().replace(":", "\\:")));
    assertThat(result).containsExactly(existingFile, "string");
  }
}
