// Copyright 2013 Google Inc. 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.enterprise.adaptor.prebuilt;

import static org.junit.Assert.*;

import com.google.enterprise.adaptor.DocumentTransform;
import com.google.enterprise.adaptor.Metadata;

import org.junit.*;
import org.junit.rules.ExpectedException;

import java.util.*;

/** Unit tests for {@link PrebuiltTransfors}. */
public class PrebuiltTransformsTest {
  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Test
  public void testCopy() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("1.from", "colour");
    config.put("1.to", "color");
    config.put("2.from", "author");
    config.put("2.to", "contributors");
    config.put("3.from", "color");
    config.put("3.to", "favorite");
    config.put("4.from", "missing");
    config.put("4.to", "favorite");
    config.put("trash.from", "colour");
    config.put("trash.to", "not used");
    config.put("5.from", "colour");
    config.put("6.to", "colour");
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.copyMetadata(config);

    final Metadata metadataGolden;
    {
      Metadata golden = new Metadata();
      golden.add("colour", "black");
      golden.add("color", "black");
      golden.add("favorite", "black");
      golden.add("author", "Fred");
      golden.add("contributors", "Mary");
      golden.add("contributors", "George");
      golden.add("contributors", "Fred");
      metadataGolden = golden.unmodifiableView();
    }
    Metadata metadata = new Metadata();
    metadata.add("colour", "black");
    metadata.add("author", "Fred");
    metadata.add("contributors", "Mary");
    metadata.add("contributors", "George");
    transform.transform(metadata, new HashMap<String, String>());
    assertEquals(metadataGolden, metadata);
  }

  @Test
  public void testCopyToString() {
    Map<String, String> config = new HashMap<String, String>();
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.copyMetadata(config);
    assertEquals("CopyTransform(copies=[],overwrite=false,move=false)",
        transform.toString());
  }

  @Test
  public void testMove() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("overwrite", "true");
    config.put("1.from", "colour");
    config.put("1.to", "color");
    config.put("2.from", "author");
    config.put("2.to", "contributors");
    config.put("3.from", "color");
    config.put("3.to", "favorite");
    config.put("4.from", "missing");
    config.put("4.to", "favorite");
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.moveMetadata(config);

    final Metadata metadataGolden;
    {
      Metadata golden = new Metadata();
      golden.add("favorite", "black");
      golden.add("contributors", "Fred");
      metadataGolden = golden.unmodifiableView();
    }
    Metadata metadata = new Metadata();
    metadata.add("colour", "black");
    metadata.add("author", "Fred");
    metadata.add("contributors", "Mary");
    metadata.add("contributors", "George");
    transform.transform(metadata, new HashMap<String, String>());
    assertEquals(metadataGolden, metadata);
  }

  @Test
  public void testMoveToString() {
    Map<String, String> config = new HashMap<String, String>();
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.moveMetadata(config);
    assertEquals("CopyTransform(copies=[],overwrite=false,move=true)",
        transform.toString());
  }

  @Test
  public void testDelete() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("key1", "missing");
    config.put("key3", "author");
    config.put("keyy", "contributors");
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.deleteMetadata(config);

    final Metadata metadataGolden;
    {
      Metadata golden = new Metadata();
      golden.add("colour", "black");
      golden.add("contributors", "Mary");
      golden.add("contributors", "George");
      metadataGolden = golden.unmodifiableView();
    }
    Metadata metadata = new Metadata();
    metadata.add("colour", "black");
    metadata.add("author", "Fred");
    metadata.add("contributors", "Mary");
    metadata.add("contributors", "George");
    transform.transform(metadata, new HashMap<String, String>());
    assertEquals(metadataGolden, metadata);
  }

  @Test
  public void testDeleteToString() {
    Map<String, String> config = new HashMap<String, String>();
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.deleteMetadata(config);
    assertEquals("DeleteTransform(keys=[])", transform.toString());
  }

  @Test
  public void testReplacePattern() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("key1", "colour");
    config.put("key2", "missing");
    config.put("key4", "contributors");
    config.put("pattern", "[aeiou]");
    config.put("replacement", "$0$0");
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.replaceMetadata(config);

    final Metadata metadataGolden;
    {
      Metadata golden = new Metadata();
      golden.add("colour", "blaack");
      golden.add("author", "Fred");
      golden.add("contributors", "Maary");
      golden.add("contributors", "Geeoorgee");
      metadataGolden = golden.unmodifiableView();
    }
    Metadata metadata = new Metadata();
    metadata.add("colour", "black");
    metadata.add("author", "Fred");
    metadata.add("contributors", "Mary");
    metadata.add("contributors", "George");
    transform.transform(metadata, new HashMap<String, String>());
    assertEquals(metadataGolden, metadata);
  }

  @Test
  public void testReplaceString() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("overwrite", "false");
    config.put("key1", "colour");
    config.put("key2", "missing");
    config.put("key4", "contributors");
    config.put("string", "[test]");
    config.put("replacement", "$0");
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.replaceMetadata(config);

    final Metadata metadataGolden;
    {
      Metadata golden = new Metadata();
      golden.add("colour", "black [test]");
      golden.add("colour", "black $0");
      golden.add("author", "Fred [test]");
      golden.add("contributors", "Ma[test]ry[test]");
      golden.add("contributors", "Ma$0ry$0");
      golden.add("contributors", "George");
      metadataGolden = golden.unmodifiableView();
    }
    Metadata metadata = new Metadata();
    metadata.add("colour", "black [test]");
    metadata.add("author", "Fred [test]");
    metadata.add("contributors", "Ma[test]ry[test]");
    metadata.add("contributors", "George");
    transform.transform(metadata, new HashMap<String, String>());
    assertEquals(metadataGolden, metadata);
  }

  @Test
  public void testReplaceToString() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("string", "tofind");
    config.put("replacement", "replace$0");
    config = Collections.unmodifiableMap(config);

    DocumentTransform transform = PrebuiltTransforms.replaceMetadata(config);
    assertEquals("ReplaceTransform(keys=[],toMatch=\\Qtofind\\E,"
        + "replacement=replace\\$0,overwrite=true)", transform.toString());
  }

  @Test
  public void testReplaceMissingStringAndPattern() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("replacement", "replace$0");
    config = Collections.unmodifiableMap(config);

    thrown.expect(IllegalArgumentException.class);
    DocumentTransform transform = PrebuiltTransforms.replaceMetadata(config);
  }

  @Test
  public void testReplaceBothStringAndPattern() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("string", "tofind");
    config.put("pattern", "tofind");
    config.put("replacement", "replace$0");
    config = Collections.unmodifiableMap(config);

    thrown.expect(IllegalArgumentException.class);
    DocumentTransform transform = PrebuiltTransforms.replaceMetadata(config);
  }

  @Test
  public void testReplaceMissingReplacement() {
    Map<String, String> config = new HashMap<String, String>();
    config.put("string", "tofind");
    config = Collections.unmodifiableMap(config);

    thrown.expect(IllegalArgumentException.class);
    DocumentTransform transform = PrebuiltTransforms.replaceMetadata(config);
  }
}
