/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.rest.internal.web.controllers;

import java.util.Date;

import org.apache.geode.internal.lang.ObjectUtils;
import org.apache.geode.pdx.PdxReader;
import org.apache.geode.pdx.PdxSerializable;
import org.apache.geode.pdx.PdxWriter;

/**
 * The Person class is an abstraction modeling a person.
 * <p>
 *
 * @since GemFire 8.0
 */
@SuppressWarnings("unused")
public class Person implements PdxSerializable {

  private static final long serialVersionUID = 42108163264l;

  protected static final String DOB_FORMAT_PATTERN = "MM/dd/yyyy";

  private Long id;

  private Date birthDate;

  private Gender gender;

  private String firstName;
  private String middleName;
  private String lastName;

  public Person() {}

  public Person(final Long id) {
    this.id = id;
  }

  public Person(final String firstName, final String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public Person(Long id, String fn, String mn, String ln, Date bDate, Gender g) {
    this.id = id;
    firstName = fn;
    middleName = mn;
    lastName = ln;
    birthDate = bDate;
    gender = g;
  }

  public Long getId() {
    return id;
  }

  public void setId(final Long id) {
    this.id = id;
  }

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(final String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(final String lastName) {
    this.lastName = lastName;
  }

  public String getMiddleName() {
    return middleName;
  }

  public void setMiddleName(final String middleName) {
    this.middleName = middleName;
  }

  public Date getBirthDate() {
    return birthDate;
  }

  public void setBirthDate(final Date birthDate) {
    this.birthDate = birthDate;
  }

  public Gender getGender() {
    return gender;
  }

  public void setGender(final Gender gender) {
    this.gender = gender;
  }

  @Override
  public boolean equals(final Object obj) {
    if (obj == this) {
      return true;
    }

    if (!(obj instanceof Person)) {
      return false;
    }

    final Person that = (Person) obj;

    return (ObjectUtils.equals(getId(), that.getId())
        || (ObjectUtils.equals(getBirthDate(), that.getBirthDate())
            && ObjectUtils.equals(getLastName(), that.getLastName())
            && ObjectUtils.equals(getFirstName(), that.getFirstName())));
  }

  @Override
  public int hashCode() {
    int hashValue = 17;
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getId());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getBirthDate());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getLastName());
    hashValue = 37 * hashValue + ObjectUtils.hashCode(getFirstName());
    return hashValue;
  }

  @Override
  public String toString() {
    return "{ type = " + getClass().getName()
        + ", id = " + getId()
        + ", firstName = " + getFirstName()
        + ", middleName = " + getMiddleName()
        + ", lastName = " + getLastName()
        + ", birthDate = "
        + DateTimeUtils.format(getBirthDate(), DOB_FORMAT_PATTERN)
        + ", gender = " + getGender()
        + " }";
  }

  @Override
  public void toData(PdxWriter writer) {
    writer.writeString("@type", getClass().getName());
    writer.writeLong("id", id);
    writer.writeString("firstName", firstName);
    writer.writeString("middleName", middleName);
    writer.writeString("lastName", lastName);
    writer.writeObject("gender", gender);
    writer.writeDate("birthDate", birthDate);

  }

  @Override
  public void fromData(PdxReader reader) {
    String type = reader.readString("@type");
    id = reader.readLong("id");
    firstName = reader.readString("firstName");
    middleName = reader.readString("middleName");
    lastName = reader.readString("lastName");
    gender = (Gender) reader.readObject("gender");
    birthDate = reader.readDate("birthDate");

  }

}
