package org.kar.karideo.migration;

import java.util.List;

import org.kar.archidata.api.DataResource;
import org.kar.archidata.dataAccess.DBAccess;
import org.kar.archidata.externalRestApi.AnalyzeApi;
import org.kar.archidata.externalRestApi.TsGenerateApi;
import org.kar.archidata.migration.MigrationSqlStep;
import org.kar.archidata.model.Data;
import org.kar.archidata.model.User;
import org.kar.archidata.model.token.JwtToken;
import org.kar.karideo.api.Front;
import org.kar.karideo.api.HealthCheck;
import org.kar.karideo.api.MediaResource;
import org.kar.karideo.api.SeasonResource;
import org.kar.karideo.api.SeriesResource;
import org.kar.karideo.api.TypeResource;
import org.kar.karideo.api.UserMediaAdvancementResource;
import org.kar.karideo.api.UserResource;
import org.kar.karideo.model.Media;
import org.kar.karideo.model.Season;
import org.kar.karideo.model.Series;
import org.kar.karideo.model.Type;
import org.kar.karideo.model.UserMediaAdvancement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Initialization extends MigrationSqlStep {
	private static final Logger LOGGER = LoggerFactory.getLogger(Initialization.class);

	public static final int KARSO_INITIALISATION_ID = 1;

	public static final List<Class<?>> CLASSES_BASE = List.of(Data.class, Media.class, Type.class, Series.class, Season.class, User.class, UserMediaAdvancement.class);

	@Override
	public String getName() {
		return "Initialization";
	}

	public static void generateObjects() throws Exception {
		LOGGER.info("Generate APIs");
		final List<Class<?>> listOfResources = List.of(Front.class, HealthCheck.class, SeasonResource.class, SeriesResource.class, TypeResource.class, UserMediaAdvancementResource.class,
				UserResource.class, MediaResource.class, DataResource.class);
		final AnalyzeApi api = new AnalyzeApi();
		api.addAllApi(listOfResources);
		api.addModel(JwtToken.class);
		TsGenerateApi.generateApi(api, "../front/src/back-api/");
		LOGGER.info("Generate APIs (DONE)");
	}

	@Override
	public void generateStep() throws Exception {
		for (final Class<?> clazz : CLASSES_BASE) {
			addClass(clazz);
		}

		addAction((final DBAccess da) -> {
			final List<Type> data = List.of(//
					new Type("Documentary", "Documentary (animals, space, earth...)"), //
					new Type("Movie", "Movie with real humans (film)"), //
					new Type("Animation", "Animation movies (film)"), //
					new Type("Short movie", "Small movies (less 2 minutes)"), //
					new Type("TV show", "TV show for old peoples"), //
					new Type("Animation TV show", "TV show for young peoples"), //
					new Type("Theater", "Theater play"), //
					new Type("One man show", "Recorded stand up"), //
					new Type("Concert", "Recorded concert"), //
					new Type("Opera", "Recorded opera") //
			);
			da.insertMultiple(data);
		});
		// set start increment element to permit to add after default elements
		addAction("""
				ALTER TABLE `media` AUTO_INCREMENT = 1000;
				""", "mysql");
		addAction("""
				ALTER TABLE `type` AUTO_INCREMENT = 1000;
				""", "mysql");
		addAction("""
				ALTER TABLE `series` AUTO_INCREMENT = 1000;
				""", "mysql");
		addAction("""
				ALTER TABLE `season` AUTO_INCREMENT = 1000;
				""", "mysql");
		addAction("""
				ALTER TABLE `userMediaAdvancement` AUTO_INCREMENT = 1000;
				""", "mysql");
	}

	public static void dropAll(final DBAccess da) {
		for (final Class<?> element : CLASSES_BASE) {
			try {
				da.drop(element);
			} catch (final Exception ex) {
				LOGGER.error("Fail to drop table !!!!!!");
				ex.printStackTrace();
			}
		}
	}

	public static void cleanAll(final DBAccess da) {
		for (final Class<?> element : CLASSES_BASE) {
			try {
				da.cleanAll(element);
			} catch (final Exception ex) {
				LOGGER.error("Fail to clean table !!!!!!");
				ex.printStackTrace();
			}
		}
	}
}
