-- folders may be deleted independently. Don't cascade
CREATE TABLE `folders` (
  `id` integer not null primary key autoincrement,
  `path` varchar(255) NOT NULL,
  `parent_folder_id` integer,
  `mod_time` datetime not null,
  `created_at` datetime not null,
  `updated_at` datetime not null,
  foreign key(`parent_folder_id`) references `folders`(`id`) on delete SET NULL
);

CREATE INDEX `index_folders_on_parent_folder_id` on `folders` (`parent_folder_id`);
CREATE UNIQUE INDEX `index_folders_on_path_unique` on `folders` (`path`);

-- require reference folders/zip files to be deleted manually first
CREATE TABLE `files` (
  `id` integer not null primary key autoincrement,
  `basename` varchar(255) NOT NULL,
  `zip_file_id` integer,
  `parent_folder_id` integer not null,
  `size` integer NOT NULL,
  `mod_time` datetime not null,
  `created_at` datetime not null,
  `updated_at` datetime not null,
  foreign key(`parent_folder_id`) references `folders`(`id`),
  foreign key(`zip_file_id`) references `files`(`id`),
  CHECK (`basename` != '')
);

CREATE UNIQUE INDEX `index_files_zip_basename_unique` ON `files` (`zip_file_id`, `parent_folder_id`, `basename`) WHERE `zip_file_id` IS NOT NULL;
CREATE UNIQUE INDEX `index_files_on_parent_folder_id_basename_unique` on `files` (`parent_folder_id`, `basename`);
CREATE INDEX `index_files_on_basename` on `files` (`basename`);

ALTER TABLE `folders` ADD COLUMN `zip_file_id` integer REFERENCES `files`(`id`);
CREATE INDEX `index_folders_on_zip_file_id` on `folders` (`zip_file_id`) WHERE `zip_file_id` IS NOT NULL;

CREATE TABLE `files_fingerprints` (
  `file_id` integer NOT NULL,
  `type` varchar(255) NOT NULL,
  `fingerprint` blob NOT NULL,
  foreign key(`file_id`) references `files`(`id`) on delete CASCADE,
  PRIMARY KEY (`file_id`, `type`, `fingerprint`)
);

CREATE INDEX `index_fingerprint_type_fingerprint` ON `files_fingerprints` (`type`, `fingerprint`);

CREATE TABLE `video_files` (
  `file_id` integer NOT NULL primary key,
  `duration` float NOT NULL,
	`video_codec` varchar(255) NOT NULL,
	`format` varchar(255) NOT NULL,
	`audio_codec` varchar(255) NOT NULL,
	`width` tinyint NOT NULL,
	`height` tinyint NOT NULL,
	`frame_rate` float NOT NULL,
	`bit_rate` integer NOT NULL,
  `interactive` boolean not null default '0',
  `interactive_speed` int,
  foreign key(`file_id`) references `files`(`id`) on delete CASCADE
);

CREATE TABLE `video_captions` (
  `file_id` integer NOT NULL,
  `language_code` varchar(255) NOT NULL,
  `filename` varchar(255) NOT NULL,
  `caption_type` varchar(255) NOT NULL,
  primary key (`file_id`, `language_code`, `caption_type`),
  foreign key(`file_id`) references `video_files`(`file_id`) on delete CASCADE
);

CREATE TABLE `image_files` (
  `file_id` integer NOT NULL primary key,
  `format` varchar(255) NOT NULL,
  `width` tinyint NOT NULL,
	`height` tinyint NOT NULL,
  foreign key(`file_id`) references `files`(`id`) on delete CASCADE
);

CREATE TABLE `images_files` (
    `image_id` integer NOT NULL,
    `file_id` integer NOT NULL,
    `primary` boolean NOT NULL,
    foreign key(`image_id`) references `images`(`id`) on delete CASCADE,
    foreign key(`file_id`) references `files`(`id`) on delete CASCADE,
    PRIMARY KEY(`image_id`, `file_id`)
);

CREATE INDEX `index_images_files_on_file_id` on `images_files` (`file_id`);

CREATE TABLE `galleries_files` (
    `gallery_id` integer NOT NULL,
    `file_id` integer NOT NULL,
    `primary` boolean NOT NULL,
    foreign key(`gallery_id`) references `galleries`(`id`) on delete CASCADE,
    foreign key(`file_id`) references `files`(`id`) on delete CASCADE,
    PRIMARY KEY(`gallery_id`, `file_id`)
);

CREATE INDEX `index_galleries_files_file_id` ON `galleries_files` (`file_id`);

CREATE TABLE `scenes_files` (
    `scene_id` integer NOT NULL,
    `file_id` integer NOT NULL,
    `primary` boolean NOT NULL,
    foreign key(`scene_id`) references `scenes`(`id`) on delete CASCADE,
    foreign key(`file_id`) references `files`(`id`) on delete CASCADE,
    PRIMARY KEY(`scene_id`, `file_id`)
);

CREATE INDEX `index_scenes_files_file_id` ON `scenes_files` (`file_id`);

PRAGMA foreign_keys=OFF;

CREATE TABLE `images_new` (
  `id` integer not null primary key autoincrement,
  -- REMOVED: `path` varchar(510) not null,
  -- REMOVED: `checksum` varchar(255) not null,
  `title` varchar(255),
  `rating` tinyint,
  -- REMOVED: `size` integer,
  -- REMOVED: `width` tinyint,
  -- REMOVED: `height` tinyint,
  `studio_id` integer,
  `o_counter` tinyint not null default 0,
  `organized` boolean not null default '0',
  -- REMOVED: `file_mod_time` datetime,
  `created_at` datetime not null,
  `updated_at` datetime not null,
  foreign key(`studio_id`) references `studios`(`id`) on delete SET NULL
);

INSERT INTO `images_new`
  (
    `id`,
    `title`,
    `rating`,
    `studio_id`,
    `o_counter`,
    `organized`,
    `created_at`,
    `updated_at`
  )
  SELECT 
    `id`,
    `title`,
    `rating`,
    `studio_id`,
    `o_counter`,
    `organized`,
    `created_at`,
    `updated_at`
  FROM `images`;

-- create temporary placeholder folder
INSERT INTO `folders` (`path`, `mod_time`, `created_at`, `updated_at`) VALUES ('', '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00');

-- insert image files - we will fix these up in the post-migration
INSERT INTO `files`
  (
    `basename`,
    `parent_folder_id`,
    `size`,
    `mod_time`,
    `created_at`,
    `updated_at`
  )
  SELECT
    `path`,
    1,
    COALESCE(`size`, 0),
    -- set mod time to epoch so that it the format/size is calculated on scan
    '1970-01-01 00:00:00',
    `created_at`,
    `updated_at`
  FROM `images`;

INSERT INTO `image_files`
  (
    `file_id`,
    `format`,
    `width`,
    `height`
  )
  SELECT
    `files`.`id`,
    '',
    COALESCE(`images`.`width`, 0),
    COALESCE(`images`.`height`, 0)
  FROM `images` INNER JOIN `files` ON `images`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

INSERT INTO `images_files`
  (
    `image_id`,
    `file_id`,
    `primary`
  )
  SELECT
    `images`.`id`,
    `files`.`id`,
    1
  FROM `images` INNER JOIN `files` ON `images`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

INSERT INTO `files_fingerprints`
  (
    `file_id`,
    `type`,
    `fingerprint`
  )
  SELECT
    `files`.`id`,
    'md5',
    `images`.`checksum`
  FROM `images` INNER JOIN `files` ON `images`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

DROP TABLE `images`;
ALTER TABLE `images_new` rename to `images`;

CREATE INDEX `index_images_on_studio_id` on `images` (`studio_id`);


CREATE TABLE `galleries_new` (
  `id` integer not null primary key autoincrement,
  -- REMOVED: `path` varchar(510),
  -- REMOVED: `checksum` varchar(255) not null,
  -- REMOVED: `zip` boolean not null default '0',
  `folder_id` integer,
  `title` varchar(255),
  `url` varchar(255),
  `date` date,
  `details` text,
  `studio_id` integer,
  `rating` tinyint,
  -- REMOVED: `file_mod_time` datetime,
  `organized` boolean not null default '0',
  `created_at` datetime not null,
  `updated_at` datetime not null,
  foreign key(`studio_id`) references `studios`(`id`) on delete SET NULL,
  foreign key(`folder_id`) references `folders`(`id`) on delete SET NULL
);

INSERT INTO `galleries_new`
  (
    `id`,
    `title`,
    `url`,
    `date`,
    `details`,
    `studio_id`,
    `rating`,
    `organized`,
    `created_at`,
    `updated_at`
  )
  SELECT 
    `id`,
    `title`,
    `url`,
    `date`,
    `details`,
    `studio_id`,
    `rating`,
    `organized`,
    `created_at`,
    `updated_at`
  FROM `galleries`;

-- insert gallery files - we will fix these up in the post-migration
INSERT INTO `files`
  (
    `basename`,
    `parent_folder_id`,
    `size`,
    `mod_time`,
    `created_at`,
    `updated_at`
  )
  SELECT
    `path`,
    1,
    0,
    '1970-01-01 00:00:00', -- set to placeholder so that size is updated
    `created_at`,
    `updated_at`
  FROM `galleries`
  WHERE `galleries`.`path` IS NOT NULL AND `galleries`.`zip` = '1';

-- insert gallery zip folders - we will fix these up in the post-migration
INSERT INTO `folders`
  (
    `path`,
    `zip_file_id`,
    `mod_time`,
    `created_at`,
    `updated_at`
  )
  SELECT
    `galleries`.`path`,
    `files`.`id`,
    '1970-01-01 00:00:00',
    `galleries`.`created_at`,
    `galleries`.`updated_at`
  FROM `galleries` 
  INNER JOIN `files` ON `galleries`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1
  WHERE `galleries`.`path` IS NOT NULL AND `galleries`.`zip` = '1';

-- set the zip file id of the zip folders
UPDATE `folders` SET `zip_file_id` = (SELECT `files`.`id` FROM `files` WHERE `folders`.`path` = `files`.`basename`); 

-- insert gallery folders - we will fix these up in the post-migration
INSERT INTO `folders`
  (
    `path`,
    `mod_time`,
    `created_at`,
    `updated_at`
  )
  SELECT
    `path`,
    '1970-01-01 00:00:00',
    `created_at`,
    `updated_at`
  FROM `galleries`
  WHERE `galleries`.`path` IS NOT NULL AND `galleries`.`zip` = '0';

UPDATE `galleries_new` SET `folder_id` = (
  SELECT `folders`.`id` FROM `folders` INNER JOIN `galleries` ON `galleries_new`.`id` = `galleries`.`id` WHERE `folders`.`path` = `galleries`.`path` AND `galleries`.`zip` = '0'
);

INSERT INTO `galleries_files`
  (
    `gallery_id`,
    `file_id`,
    `primary`
  )
  SELECT
    `galleries`.`id`,
    `files`.`id`,
    1
  FROM `galleries` INNER JOIN `files` ON `galleries`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

INSERT INTO `files_fingerprints`
  (
    `file_id`,
    `type`,
    `fingerprint`
  )
  SELECT
    `files`.`id`,
    'md5',
    `galleries`.`checksum`
  FROM `galleries` INNER JOIN `files` ON `galleries`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

DROP TABLE `galleries`;
ALTER TABLE `galleries_new` rename to `galleries`;

CREATE INDEX `index_galleries_on_studio_id` on `galleries` (`studio_id`);
-- should only be possible to create a single gallery per folder
CREATE UNIQUE INDEX `index_galleries_on_folder_id_unique` on `galleries` (`folder_id`);

CREATE TABLE `scenes_new` (
  `id` integer not null primary key autoincrement,
  -- REMOVED: `path` varchar(510) not null,
  -- REMOVED: `checksum` varchar(255),
  -- REMOVED: `oshash` varchar(255),
  `title` varchar(255),
  `details` text,
  `url` varchar(255),
  `date` date,
  `rating` tinyint,
  -- REMOVED: `size` varchar(255),
  -- REMOVED: `duration` float,
  -- REMOVED: `video_codec` varchar(255),
  -- REMOVED: `audio_codec` varchar(255),
  -- REMOVED: `width` tinyint,
  -- REMOVED: `height` tinyint,
  -- REMOVED: `framerate` float,
  -- REMOVED: `bitrate` integer,
  `studio_id` integer,
  `o_counter` tinyint not null default 0,
  -- REMOVED: `format` varchar(255),
  `organized` boolean not null default '0',
  -- REMOVED: `interactive` boolean not null default '0',
  -- REMOVED: `interactive_speed` int,
  `created_at` datetime not null,
  `updated_at` datetime not null,
  -- REMOVED: `file_mod_time` datetime,
  -- REMOVED: `phash` blob,
  foreign key(`studio_id`) references `studios`(`id`) on delete SET NULL
  -- REMOVED: CHECK (`checksum` is not null or `oshash` is not null)
);

INSERT INTO `scenes_new`
  (
    `id`,
    `title`,
    `details`,
    `url`,
    `date`,
    `rating`,
    `studio_id`,
    `o_counter`,
    `organized`,
    `created_at`,
    `updated_at`
  )
  SELECT 
    `id`,
    `title`,
    `details`,
    `url`,
    `date`,
    `rating`,
    `studio_id`,
    `o_counter`,
    `organized`,
    `created_at`,
    `updated_at`
  FROM `scenes`;

-- insert scene files - we will fix these up in the post-migration
INSERT INTO `files`
  (
    `basename`,
    `parent_folder_id`,
    `size`,
    `mod_time`,
    `created_at`,
    `updated_at`
  )
  SELECT
    `path`,
    1,
    COALESCE(`size`, 0),
    -- set mod time to epoch so that it the format/size is calculated on scan
    '1970-01-01 00:00:00',
    `created_at`,
    `updated_at`
  FROM `scenes`;

INSERT INTO `video_files`
  (
    `file_id`,
    `duration`,
    `video_codec`,
    `format`,
    `audio_codec`,
    `width`,
    `height`,
    `frame_rate`,
    `bit_rate`,
    `interactive`,
    `interactive_speed`
  )
  SELECT
    `files`.`id`,
    `scenes`.`duration`,
    COALESCE(`scenes`.`video_codec`, ''),
    COALESCE(`scenes`.`format`, ''),
    COALESCE(`scenes`.`audio_codec`, ''),
    COALESCE(`scenes`.`width`, 0),
    COALESCE(`scenes`.`height`, 0),
    COALESCE(`scenes`.`framerate`, 0),
    COALESCE(`scenes`.`bitrate`, 0),
    `scenes`.`interactive`,
    `scenes`.`interactive_speed`
  FROM `scenes` INNER JOIN `files` ON `scenes`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

INSERT INTO `scenes_files`
  (
    `scene_id`,
    `file_id`,
    `primary`
  )
  SELECT
    `scenes`.`id`,
    `files`.`id`,
    1
  FROM `scenes` INNER JOIN `files` ON `scenes`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

INSERT INTO `files_fingerprints`
  (
    `file_id`,
    `type`,
    `fingerprint`
  )
  SELECT
    `files`.`id`,
    'md5',
    `scenes`.`checksum`
  FROM `scenes` INNER JOIN `files` ON `scenes`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1
  WHERE `scenes`.`checksum` is not null;

INSERT INTO `files_fingerprints`
  (
    `file_id`,
    `type`,
    `fingerprint`
  )
  SELECT
    `files`.`id`,
    'oshash',
    `scenes`.`oshash`
  FROM `scenes` INNER JOIN `files` ON `scenes`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1
  WHERE `scenes`.`oshash` is not null;

INSERT INTO `files_fingerprints`
  (
    `file_id`,
    `type`,
    `fingerprint`
  )
  SELECT
    `files`.`id`,
    'phash',
    `scenes`.`phash`
  FROM `scenes` INNER JOIN `files` ON `scenes`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1
  WHERE `scenes`.`phash` is not null;

INSERT INTO `video_captions`
  (
    `file_id`,
    `language_code`,
    `filename`,
    `caption_type`
  )
  SELECT
    `files`.`id`,
    `scene_captions`.`language_code`,
    `scene_captions`.`filename`,
    `scene_captions`.`caption_type`
  FROM `scene_captions` 
  INNER JOIN `scenes` ON `scene_captions`.`scene_id` = `scenes`.`id`
  INNER JOIN `files` ON `scenes`.`path` = `files`.`basename` AND `files`.`parent_folder_id` = 1;

DROP TABLE `scenes`;
DROP TABLE `scene_captions`;

ALTER TABLE `scenes_new` rename to `scenes`;
CREATE INDEX `index_scenes_on_studio_id` on `scenes` (`studio_id`);

PRAGMA foreign_keys=ON;
