// Copyright 2008 Google Inc.
//
// 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.gwtorm.client;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import com.google.gwtorm.server.StandardKeyEncoder;
import org.junit.Before;
import org.junit.Test;

public class StringKeyTestCase {
  @SuppressWarnings("serial")
  private abstract static class StringKeyImpl<T extends Key<?>> extends StringKey<T> {
    @Column(id = 1)
    String name;

    public StringKeyImpl(String n) {
      name = n;
    }

    @Override
    public String get() {
      return name;
    }

    @Override
    protected void set(String newValue) {
      name = newValue;
    }
  }

  @SuppressWarnings("serial")
  private static class Parent extends StringKeyImpl<Key<?>> {
    public Parent(String n) {
      super(n);
    }
  }

  @SuppressWarnings("serial")
  private static class UnrelatedEntity extends StringKeyImpl<Key<?>> {
    public UnrelatedEntity(String n) {
      super(n);
    }
  }

  @SuppressWarnings("serial")
  private static class Child extends StringKeyImpl<Parent> {
    private Parent parent;

    public Child(Parent p, String n) {
      super(n);
      parent = p;
    }

    @Override
    public Parent getParentKey() {
      return parent;
    }
  }

  @Before
  public void setUp() throws Exception {
    KeyUtil.setEncoderImpl(new StandardKeyEncoder());
  }

  @Test
  public void testHashCodeWhenNull() {
    final Parent p = new Parent(null);
    assertEquals(0, p.hashCode());
  }

  @Test
  public void testParentHashCode() {
    final String str = "foo";
    final Parent p = new Parent(str);
    assertEquals(str.hashCode(), p.hashCode());
  }

  @Test
  public void testParentEquals() {
    final String str = "foo";
    final Parent p1 = new Parent(str);
    final Parent p2 = new Parent(str);
    assertTrue(p1.equals(p2));
    assertTrue(p2.equals(p1));
    assertFalse(p1.equals(null));

    final UnrelatedEntity u = new UnrelatedEntity(str);
    assertFalse(p1.equals(u));
    assertFalse(u.equals(p1));

    final Parent p3 = new Parent("bar");
    assertFalse(p1.equals(p3));
  }

  @Test
  public void testChildHashCode() {
    final String pName = "foo";
    final String cName = "bar";
    final Parent p = new Parent(pName);
    final Child c = new Child(p, cName);
    assertSame(p, c.getParentKey());
    assertTrue(cName.hashCode() != c.hashCode());
  }

  @Test
  public void testChildEquals() {
    final String pName = "foo";
    final String cName = "bar";
    final Child c1 = new Child(new Parent(pName), cName);
    final Child c2 = new Child(new Parent(pName), cName);
    assertTrue(c1.equals(c2));
    assertTrue(c2.equals(c1));
    assertFalse(c1.equals(null));

    final UnrelatedEntity u = new UnrelatedEntity("bar");
    assertFalse(c1.equals(u));
    assertFalse(u.equals(c1));
  }

  @Test
  public void testParentString() {
    final String pv = "foo,bar/ at %here";
    final Parent p1 = new Parent(pv);
    assertEquals("foo%2Cbar/+at+%25here", p1.toString());

    final Parent p2 = new Parent("");
    p2.fromString(p1.toString());
    assertEquals(p1, p2);
  }

  @Test
  public void testChildString() {
    final String pv = "foo,bar/ at %here";
    final String cv = "x";
    final Child c1 = new Child(new Parent(pv), cv);
    assertEquals("foo%2Cbar/+at+%25here,x", c1.toString());

    final Child c2 = new Child(new Parent(""), "");
    c2.fromString(c1.toString());
    assertEquals(c1, c2);
  }
}
