/*
 * Copyright (C) 2000 - 2026 Silverpeas
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * As a special exception to the terms and conditions of version 3.0 of
 * the GPL, you may redistribute this Program in connection with Free/Libre
 * Open Source Software ("FLOSS") applications as described in Silverpeas's
 * FLOSS exception. You should have received a copy of the text describing
 * the FLOSS exception, and it is also available here:
 * "http://www.silverpeas.org/docs/core/legal/floss_exception.html"
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
package org.silverpeas.components.questionreply.web;

import org.silverpeas.core.personalization.UserPreferences;
import org.silverpeas.core.personalization.service.PersonalizationServiceProvider;
import org.silverpeas.core.admin.user.model.UserDetail;
import org.silverpeas.core.ui.DisplayI18NHelper;

import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlTransient;
import java.io.Serializable;

import static org.silverpeas.kernel.util.StringUtil.isDefined;

/**
 * The entity representing the author of a comment. It is a user that has written a comment and
 * that is exposed in the web as an entity (a web entity). As such, it publishes only some of its
 * attributes.
 */
@XmlRootElement
public class AuthorEntity implements Serializable {

  private static final long serialVersionUID = 2470628480159572486L;
  @XmlElement(defaultValue = "")
  private String fullName;
  @XmlElement(required = true)
  private String id;
  @XmlElement(defaultValue = "")
  private String avatar;
  @XmlElement(defaultValue = "fr")
  private String language;

  /**
   * Creates a new comment author entity from the specified user.
   * @param user the user to entitify.
   * @return the comment writer.
   */
  public static AuthorEntity fromUser(final UserDetail user) {
    return new AuthorEntity(user);
  }

  /**
   * Gets the relative path of the user avatar.
   * @return the relative path of the URI referring the user avatar.
   */
  public String getAvatar() {
    return avatar;
  }

  /**
   * Sets the URL at which is located the user's avatar.
   * @param avatarURL the URL of the user's avatar.
   */
  public void setAvatar(String avatarURL) {
    this.avatar = avatarURL;
  }

  /**
   * Gets the unique identifier of the author.
   * @return the user identifier.
   */
  public String getId() {
    return id;
  }

  /**
   * Gets the full name of the author (both the first name and the last name).
   * @return the user full name.
   */
  public String getFullName() {
    return fullName;
  }

  /**
   * Gets the preferred language of the author.
   * @return the language code of the author according to the ISO 639-1 standard (for example "fr"
   * for french).
   */
  public String getLanguage() {
    return this.language;
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final AuthorEntity other = (AuthorEntity) obj;
    if (isDefined(id) && isDefined(other.getId())) {
      return id.equals(other.getId());
    } else {
      return fullName.equals(other.getFullName()) && avatar.equals(other.getAvatar());
    }
  }

  @Override
  public int hashCode() {
    int hash = 7;
    if (isDefined(id)) {
      hash = 59 * hash + this.id.hashCode();
    } else {
      hash = 59 * hash + (this.fullName != null ? this.fullName.hashCode() : 0);
      hash = 59 * hash + (this.avatar != null ? this.avatar.hashCode() : 0);
    }
    return hash;
  }

  /**
   * Gets a user detail from this entity.
   * @return a UserDetail instance.
   */
  public UserDetail toUser() {
    UserDetail user = new UserDetail();
    user.setId(id);
    if (isDefined(fullName)) {
      int separatorBetweenFirstAndLastName = fullName.indexOf(' ');
      user.setFirstName(fullName.substring(0, separatorBetweenFirstAndLastName));
      user.setLastName(fullName.substring(separatorBetweenFirstAndLastName + 1));
    }
    return user;
  }

  private AuthorEntity(final UserDetail userDetail) {
    if (userDetail != null) {
      this.fullName = userDetail.getDisplayedName();
      this.id = userDetail.getId();
      this.avatar = userDetail.getAvatar();
      UserPreferences prefs = getUserPreferences();
      if (prefs != null) {
        this.language = prefs.getLanguage();
      } else {
        this.language = DisplayI18NHelper.getDefaultLanguage();
      }
    }
  }

  /**
   * Creates an empty comment author.
   */
  protected AuthorEntity() {
  }

  /**
   * Gets the preference of this author.
   * @return the preferences of the user or null if its preferences cannot be retrieved.
   */
  @XmlTransient
  public final UserPreferences getUserPreferences() {
    return PersonalizationServiceProvider.getPersonalizationService().getUserSettings(this.id);
  }
}
