package api.account;

import api.APIResult;
import io.cppSerialization.PackedBooleanReader;
import io.cppSerialization.PackedBooleanWriter;
import io.cppSerialization.TotalSerializable;
import org.jetbrains.annotations.NotNull;
import replicationAnnotations.ReplicateOccurence;
import system.objectsWeight.Light;

/**
 * Provide account details: whether account exists, is online etc.
 *
 * @author andrey.kuprishov
 */
@Light
@ReplicateOccurence(needCppCode = true)
public class AccountDetails implements TotalSerializable {
  private static final long serialVersionUID = -2846618127021192251L;
  @NotNull
  private APIResult status = APIResult.FAILED;
  @NotNull
  private String reason = "";
  @NotNull
  private String accountName = "";
  @NotNull
  private String lastShardName = "";
  private boolean onAccountServer = false;
  private boolean onShard = false;
  private static final short SERIALIZATION_ID = (short) 337;

  @NotNull
  public static AccountDetails createFailed(@NotNull String accountName, @NotNull String reason) {
    return new AccountDetails(APIResult.FAILED, reason, accountName, "", false, false);
  }

  public AccountDetails() {
  }

  @NotNull
  public APIResult getStatus() {
    return status;
  }

  @NotNull
  public String getReason() {
    return reason;
  }

  public AccountDetails(@NotNull APIResult status, @NotNull String reason,
                        @NotNull String accountName, @NotNull String lastShardName,
                        boolean onAccountServer, boolean onShard) {
    this.status = status;
    this.reason = reason;
    this.accountName = accountName;
    this.lastShardName = lastShardName;
    this.onAccountServer = onAccountServer;
    this.onShard = onShard;
  }

  @NotNull
  public String getAccountName() {
    return accountName;
  }

  @NotNull
  public String getLastShardName() {
    return lastShardName;
  }

  public boolean isOnAccountServer() {
    return onAccountServer;
  }

  public boolean isOnShard() {
    return onShard;
  }

  public void writeCpp(@NotNull io.cppSerialization.SerializationDataOutput out) throws io.cppSerialization.SerializationException {
    PackedBooleanWriter boolOut = new PackedBooleanWriter(out);
    boolOut.writeBoolean(onAccountServer);
    boolOut.writeBoolean(onShard);
    boolOut.flush();
    out.writeByte(status.ordinal());
    out.writeUTF(reason);
    out.writeUTF(accountName);
    out.writeUTF(lastShardName);
  }

  public void readCpp(@NotNull io.cppSerialization.SerializationDataInput in) throws io.cppSerialization.SerializationException {
    PackedBooleanReader boolIn = new PackedBooleanReader(in);
    onAccountServer = boolIn.readBoolean();
    onShard = boolIn.readBoolean();
    int statusOrdinal = (int) in.readByte();
    if (statusOrdinal >= 0 && statusOrdinal < APIResult.values().length)
      status = APIResult.values()[statusOrdinal];
    else
      throw new io.cppSerialization.SerializationException("wrong ordinal " + statusOrdinal + " of enum APIResult");
    reason = in.readUTF();
    accountName = in.readUTF();
    lastShardName = in.readUTF();
  }

  public short getID() {
    return SERIALIZATION_ID;
  }
}
