/*
 * Copyright (C) 2020 favdb
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package storybook.model.oldmodel;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import storybook.model.hbn.entity.AbstractTag;
import storybook.model.hbn.entity.AbstractTaglink;
import storybook.model.hbn.entity.Attribute;
import storybook.model.hbn.entity.Category;
import storybook.model.hbn.entity.Chapter;
import storybook.model.hbn.entity.Endnote;
import storybook.model.hbn.entity.Event;
import storybook.model.hbn.entity.Gender;
import storybook.model.hbn.entity.Idea;
import storybook.model.hbn.entity.Location;
import storybook.model.hbn.entity.Part;
import storybook.model.hbn.entity.Person;
import storybook.model.hbn.entity.Plot;
import storybook.model.hbn.entity.Relationship;
import storybook.model.hbn.entity.Scene;
import storybook.model.hbn.entity.Status;
import storybook.model.hbn.entity.Strand;
import storybook.tools.LOG;

/**
 * migration from 4.0 to 5.0
 *
 * @author favdb
 */
public class Migration40to50 {

	private Migration40to50() {
		// empty
	}

	public static boolean exec(ModelMigration mm) {
		//LOG.trace(TT+".exec(mm)");
		Connection cn = mm.connection;
		List<DbColumn> db = new ArrayList<>();
		try {
			ResultSet rs = cn.getMetaData().getColumns(null, "PUBLIC", null, null);
			while (rs.next()) {
				String table = rs.getString(3);
				String name = rs.getString(4);
				String type = rs.getString(6);
				int size = rs.getInt(7);
				DbColumn xData = new DbColumn(table, name, type, size);
				db.add(xData);
			}
		} catch (SQLException ex) {
			LOG.err("error on Migration50.exec");
			return (false);
		}
		List<DbColumn> osb = new ArrayList<>();
		getOSBcolumns(AbstractTag.getTable(), osb);
		getOSBcolumns(AbstractTaglink.getTable(), osb);
		getOSBcolumns(Attribute.getTable(), osb);
		getOSBcolumns(Category.getTable(), osb);
		getOSBcolumns(Chapter.getTable(), osb);
		getOSBcolumns(Endnote.getTable(), osb);
		getOSBcolumns(Gender.getTable(), osb);
		getOSBcolumns(Idea.getTable(), osb);
		getOSBcolumns(storybook.model.hbn.entity.Internal.getTable(), osb);
		getOSBcolumns(Location.getTable(), osb);
		getOSBcolumns(Part.getTable(), osb);
		getOSBcolumns(Person.getTable(), osb);
		getOSBcolumns(Plot.getTable(), osb);
		getOSBcolumns(Relationship.getTable(), osb);
		getOSBcolumns(Scene.getTable(), osb);
		getOSBcolumns(Status.getTable(), osb);
		getOSBcolumns(Strand.getTable(), osb);
		getOSBcolumns(Event.getTable(), osb);
		if (osb.isEmpty()) {
			LOG.trace("osb DBdata is empty");
		} else {
			for (int i = 0; i < db.size(); i++) {
				DbColumn xData = db.get(i);
				for (DbColumn oData : osb) {
					if (xData.table.equalsIgnoreCase(oData.getTable())
							&& xData.name.equalsIgnoreCase(oData.getName())
							&& oData.type.equalsIgnoreCase("String")) {
						//LOG.trace(str);
						mm.execStmt(oData.getAlter());
					}
				}
			}
		}
		return (true);
	}

	private static void getOSBcolumns(List<String> ls, List<DbColumn> osb) {
		//LOG.trace("Migration40to50.getOsbColumns(ls size="+ls.size()+",osb size="+osb.size()+")");
		for (String str : ls) {
			DbColumn xData = new DbColumn(str);
			osb.add(xData);
		}
	}

	public static class DbColumn {

		private String table;
		private String name;
		private String type;
		private int size;

		public DbColumn() {
		}

		public DbColumn(String str) {
			String s[] = str.split(",");
			setTable(s[0]);
			setName(s[1]);
			setType(s[2]);
			setSize(Integer.parseInt(s[3]));
		}

		private DbColumn(String table, String name, String type, int size) {
			this.table = table;
			this.name = name;
			this.type = type;
			this.size = size;
		}

		public void setTable(String table) {
			this.table = table;
		}

		public String getTable() {
			return table;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getName() {
			return name;
		}

		public void setType(String type) {
			this.type = type;
		}

		public String getType() {
			return type;
		}

		public void setSize(int size) {
			this.size = size;
		}

		public int getSize() {
			return size;
		}

		public String getAlter() {
			if (!type.equalsIgnoreCase("String")) {
				return ("");
			}
			String s = "ALTER TABLE " + table + " ALTER COLUMN " + name + " VARCHAR(" + size + ");";
			return (s);
		}
	}

}
