/**
 * Mail storage
 */

-- 1
CREATE TABLE address (
  address_id      INT AUTO_INCREMENT,
  address_name    TEXT,
  localpart       TEXT NOT NULL,
  domain          TEXT NOT NULL,
  email           TEXT NOT NULL,
  PRIMARY KEY (address_id),
  UNIQUE KEY (email)
);

-- 3
CREATE TABLE mailbox (
  mailbox_id      INT AUTO_INCREMENT,
  account_id      INT NOT NULL,
  mailbox_name    TEXT NOT NULL,
  uidnext         INT NOT NULL DEFAULT 1,
  nextmodseq      BIGINT NOT NULL DEFAULT 1,
  first_recent    INT NOT NULL DEFAULT 1,
  uidvalidity     INT NOT NULL DEFAULT 1,
  PRIMARY KEY (mailbox_id),
  UNIQUE KEY (mailbox_name),
  FOREIGN KEY (account_id) REFERENCES app_account(account_id) ON DELETE CASCADE
);

-- 4
CREATE TABLE message (
  message_id      INT AUTO_INCREMENT,
  messageID       TEXT NOT NULL,
  idate           TIMESTAMP NOT NULL,
  rfc822size      INT NOT NULL,
  PRIMARY KEY (message_id),
  UNIQUE KEY (messageID)
);

-- 5
-- if mailbox_message deleted message is not deleted
CREATE TABLE mailbox_message (
  mailbox_id      INT NOT NULL,
  uid             INT,
  message_id      INT,
  modseq          BIGINT NOT NULL,
  seen            BIT(1) NOT NULL DEFAULT 0,
  deleted         BIT(1) NOT NULL DEFAULT 0,
  PRIMARY KEY (uid, message_id),
  FOREIGN KEY (mailbox_id) REFERENCES mailbox(mailbox_id) ON DELETE CASCADE,
  FOREIGN KEY (message_id) REFERENCES message(message_id) ON DELETE CASCADE
);

-- 6
CREATE TABLE part_number (
  message_id    INT NOT NULL,
  part          VARCHAR(128) NOT NULL,
  bodypart_id   INT NOT NULL,
  bytes         INT,
  nb_lines      INT,
  PRIMARY KEY (message_id, part),
  FOREIGN KEY (message_id) REFERENCES message(message_id) ON DELETE CASCADE,
  FOREIGN KEY (bodypart_id) REFERENCES bodypart(bodypart_id) ON DELETE CASCADE
);

-- 7
CREATE TABLE bodypart (
  bodypart_id   INT AUTO_INCREMENT,
  bytes         INT NOT NULL,
  hash          TEXT NOT NULL,
  text          TEXT,
  data          BINARY,
  PRIMARY KEY (bodypart_id)
);

-- 8
CREATE TABLE field_name (
  field_id      INT AUTO_INCREMENT,
  field_name    VARCHAR (255),
  PRIMARY KEY (field_id),
  UNIQUE KEY (field_name)
);

-- 9
CREATE TABLE header_field (
  message_id      INT NOT NULL,
  part            VARCHAR(128) NOT NULL,
  position        INT NOT NULL,
  field_id        INT NOT NULL,
  value           TEXT NOT NULL,
  UNIQUE KEY (message_id, part, position, field_id),
  FOREIGN KEY (message_id, part) REFERENCES part_number(message_id, part) ON DELETE CASCADE,  
  FOREIGN KEY (field_id) REFERENCES field_name(field_id)
);

-- 10
CREATE TABLE address_field (
  message_id      INT NOT NULL,
  part            VARCHAR(128) NOT NULL,
  position        INT NOT NULL,
  field_id        INT NOT NULL,
  number          INT,
  address_id      INT NOT NULL,
  FOREIGN KEY (message_id, part) REFERENCES part_number(message_id, part) ON DELETE CASCADE,
  FOREIGN KEY (field_id) REFERENCES field_name(field_id),
  FOREIGN KEY (address_id) REFERENCES address(address_id)
);

/**
 * App table
 */

-- 2
CREATE TABLE app_account (
  account_id      INT AUTO_INCREMENT,
  user_id         INT NOT NULL,
  account_pwd     BINARY(22),
  xoauth          VARCHAR(116),
  xoauth2         VARCHAR(116),
  host            VARCHAR(255) NOT NULL DEFAULT 'localhost',
  port            INT(5) NOT NULL DEFAULT 143,
  tls             BIT(1) NOT NULL DEFAULT 1,
  PRIMARY KEY (account_id),
  FOREIGN KEY (user_id) REFERENCES address(address_id) ON DELETE CASCADE
);

-- 11
CREATE TABLE app_room (
  room_id         INT AUTO_INCREMENT,
  room_name       VARCHAR(30) NOT NULL,
  owner_id        INT NOT NULL,
  isGroup         BIT(1) NOT NULL DEFAULT 0,
  notSeen         INT NOT NULL DEFAULT 0,
  lastUpdate      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(),
  PRIMARY KEY (room_id),
  FOREIGN KEY (owner_id) REFERENCES address(address_id)
);

-- 12
CREATE TABLE app_thread (
  thread_id       INT AUTO_INCREMENT,
  room_id         INT NOT NULL,
  thread_name     VARCHAR(30) NOT NULL,
  notSeen         INT NOT NULL DEFAULT 0,
  lastUpdate      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(),
  isDm            BIT(1) NOT NULL DEFAULT 0,
  PRIMARY KEY (thread_id),
  FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE CASCADE
);

-- 13
CREATE TABLE app_room_message (
  message_id      INT NOT NULL,
  room_id         INT,
  thread_id       INT,
  FOREIGN KEY (message_id) REFERENCES message(message_id) ON DELETE CASCADE,
  FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE SET NULL,
  FOREIGN KEY (thread_id) REFERENCES app_thread(thread_id) ON DELETE SET NULL
);

-- 14
CREATE TABLE app_room_member (
  room_id        INT NOT NULL,
  member_id       INT NOT NULL,
  FOREIGN KEY (room_id) REFERENCES app_room(room_id) ON DELETE CASCADE,
  FOREIGN KEY (member_id) REFERENCES address(address_id)
);

-- 14
CREATE TABLE app_thread_member (
  thread_id        INT NOT NULL,
  member_id       INT NOT NULL,
  FOREIGN KEY (thread_id) REFERENCES app_thread(thread_id) ON DELETE CASCADE,
  FOREIGN KEY (member_id) REFERENCES address(address_id)
);
