using System;

using Sisyphus;

namespace Examples {

  public enum UserTitle {
    Unknown = 0,
    Mr = 1,
    Miss = 2,
    Mrs = 3
  }

  [SpfTypeStorage(TableName = "tbUsers")]
  public class User : SpfEntity {

    [SpfStringDataType(16)]
    public string Username;

    [SpfStringDataType(16)]
    public string Password;

    [SpfFieldStorage(IsLoaded = false, IsSaved = false)]
    public string PasswordConfirmation;

    [SpfFieldStorage("UserTitle")]
    public UserTitle Title;

    [SpfStringDataType(32)]
    public string Forename;

    [SpfStringDataType(64)]
    public string Surname;

    [SpfStringDataType(256)]
    public string AddressLine1;

    [SpfStringDataType(256, true)]
    public string AddressLine2;

    [SpfStringDataType(256, true)]
    public string AddressLine3;

    public DateTime DateCreated;

    public DateTime DateModified;

    public class ByUsername : SpfEntityCriteria {
      public ByUsername(string p_Username) : base(
        typeof(User),
        "SELECT Id FROM tbUsers WHERE Username = {0}",
        new object[] {p_Username}
      ) {}
    }

    public User() {

      AddConstraint(new SpfConstraint(UsernameIsUnique), SpfPersistenceAction.Insert);

    }

    public SpfBrokenConstraint UsernameIsUnique(ISpfTxnContext p_TxnContext, object p_AppContext) {

      bool usernameExists 
          = p_TxnContext.RetrieveMatchExists(p_AppContext, new User.ByUsername(this.Username));

      if (usernameExists) {
        return new SpfBrokenConstraint("The username " + this.Username + " is not unique", "Username");
      }
      else {
        return null;
      }

    }

  }

}