// 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 com.google.gwtorm.server.StandardKeyEncoder;

import junit.framework.TestCase;


public class LongKeyTestCase extends TestCase {
  private abstract static class LongKeyImpl<T extends Key<?>> extends
      LongKey<T> {
    @Column
    long id;

    public LongKeyImpl(long n) {
      id = n;
    }

    @Override
    public long get() {
      return id;
    }

    @Override
    protected void set(long newValue) {
      id = newValue;
    }
  }

  private static class Parent extends LongKeyImpl<Key<?>> {
    public Parent(long n) {
      super(n);
    }
  }

  private static class UnrelatedEntity extends LongKeyImpl<Key<?>> {
    public UnrelatedEntity(long n) {
      super(n);
    }
  }

  private static class Child extends LongKeyImpl<Parent> {
    private Parent parent;

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

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

  @Override
  protected void setUp() throws Exception {
    KeyUtil.setEncoderImpl(new StandardKeyEncoder());
  }

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

  public void testParentHashCode() {
    final long id = 21281821821821881L;
    final Parent p = new Parent(id);
    assertEquals((int) id, p.hashCode());
  }

  public void testParentEquals() {
    final long id = 21281821821821881L;
    final Parent p1 = new Parent(id);
    final Parent p2 = new Parent(id);
    assertTrue(p1.equals(p1));
    assertTrue(p1.equals(p2));
    assertTrue(p2.equals(p1));
    assertFalse(p1.equals(null));

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

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

  public void testChildHashCode() {
    final long pId = 21281821821821881L;
    final long cId = 8;
    final Parent p = new Parent(pId);
    final Child c = new Child(p, cId);
    assertSame(p, c.getParentKey());
    assertTrue(cId != c.hashCode());
  }

  public void testChildEquals() {
    final long pId = 21281821821821881L;
    final long cId = 8;
    final Child c1 = new Child(new Parent(pId), cId);
    final Child c2 = new Child(new Parent(pId), cId);
    assertTrue(c1.equals(c1));
    assertTrue(c1.equals(c2));
    assertTrue(c2.equals(c1));
    assertFalse(c1.equals(null));

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

  public void testParentString() {
    final long pId = 21281821821821881L;
    final Parent p1 = new Parent(pId);
    assertEquals("" + pId, p1.toString());

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

  public void testChildString() {
    final long pId = 21281821821821881L;
    final long cId = 18218181281818888L;
    final Child c1 = new Child(new Parent(pId), cId);
    assertEquals(pId + "," + cId, c1.toString());

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