package de.insignificance;

/*
 Copyright 2012,2013 Sebastian Lederer

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import de.dassit.dbwrapper.Entry;

public class Profile extends Entry {
	int id;
	String name;
	String alternateProfile;
	String owner;
	String description;
	String configExtras;

	public Profile() {
		keyName = "id";
		tableName = "profiles";
	}

	@Override
	public void validate() throws SQLException {
		verifySqlString(name);
		verifySqlString(alternateProfile);
		verifySqlString(owner);
		verifySqlString(description);
		verifySqlString(configExtras);
	}

	@Override
	public void initFromQuery(ResultSet queryResult) throws SQLException {
		id = queryResult.getInt(1);
		name = queryResult.getString(2);
		alternateProfile = queryResult.getString(3);
		owner = queryResult.getString(4);
		description = queryResult.getString(5);
		configExtras = queryResult.getString(6);
	}

	@Override
	public Entry newFromQuery(ResultSet rs) throws SQLException {
		Profile p = new Profile();
		p.initFromQuery(rs);
		return (Entry) p;
	}

	@Override
	public String getSelectStatement() {
		return "SELECT * FROM profiles";
	}

	@Override
	public String getWhereClause(String key) {
		return "WHERE name='" + key + "'";
	}

	@Override
	public String getInsertStatement() {
		return "INSERT INTO profiles (name,alternateprofile,owner,description,config_extras) "
				+ "VALUES("
				+ sqlStringValueComma(name)
				+ sqlStringValueComma(alternateProfile)
				+ sqlStringValueComma(owner)
				+ sqlStringValueComma(description)
				+ sqlStringValue(configExtras) + ")";

	}

	@Override
	public String getUpdateStatement() {
		return "UPDATE profiles SET " + sqlStringValueComma(name, "name")
				+ sqlStringValueComma(alternateProfile, "alternateprofile")
				+ sqlStringValueComma(owner, "owner")
				+ sqlStringValueComma(description, "description")
				+ sqlStringValue(configExtras, "config_extras") + " WHERE id="
				+ id;
	}

	@Override
	public String getDeleteStatement() {
		return "DELETE FROM profiles WHERE id=" + id;
	}

	@Override
	public String getRenameStatement(String newName) {
		return "UPDATE profiles SET " + sqlStringValue(newName, "name")
				+ " WHERE id=" + id;
	}

	@Override
	public String getCreateStatement() {
		return "DROP TABLE IF EXISTS profiles;CREATE TABLE profiles (id INTEGER AUTO_INCREMENT PRIMARY KEY, name VARCHAR(80) UNIQUE, alternateProfile VARCHAR(80), "
				+ "owner VARCHAR(80),"
				+ "description VARCHAR(512), config_extras VARCHAR(128))";
	}

	public void addPackageList(PackageList pl) throws SQLException {
		ProfileMembership m = new ProfileMembership();
		m.profileId = id;
		m.packageListId = pl.id;
		m.save();
	}

	public void removePackageList(PackageList pl) throws SQLException {
		ProfileMembership m = new ProfileMembership();
		m.profileId = id;
		m.packageListId = pl.id;
		m.delete();
	}

	public List<Entry> getPackageLists() throws SQLException {
		PackageList factory = new PackageList();
		List<Entry> result = new ArrayList<Entry>();

		String sql = "SELECT pl.id, pl.name,pl.origin,"
				+ "pl.priority,pl.approvalRequired,pl.approved,pl.atomic,pl.owner,"
				+ "pl.autoupdate,pl.description"
				+ " FROM package_lists AS pl, profile_members AS pm "
				+ "WHERE pl.id=pm.list_id AND pm.profile_id=" + id
				+ " ORDER BY pl.name";
		// System.out.println(sql);
		Statement s = getStatement();
		ResultSet rs = null;

		try {
			rs = s.executeQuery(sql);
			while (rs.next()) {
				result.add(factory.newFromQuery(rs));
			}
		} finally {
			releaseResultSet(rs);
			releaseStatement(s);
		}
		return result;
	}

	public void updatePackageLists() throws SQLException {
		List<Entry> plists = getPackageLists();

		Statement s = getStatement();
		Connection c = s.getConnection();
		try {
			c.setAutoCommit(false);
			for (Entry e : plists) {
				PackageList pl = (PackageList) e;
				if (pl.origin != 0) {
					pl.copyFrom(pl.origin);
				}
			}
		} finally {
			c.setAutoCommit(true);
			releaseStatement(s);
		}
	}

	public boolean checkApprovals() throws SQLException {
		boolean result;
		String sql = "SELECT origs.id, origs.name"
				+ " FROM package_lists AS pl, profile_members AS pm, "
				+ "  package_lists as origs"
				+ " WHERE pl.id=pm.list_id AND pm.profile_id="
				+ id
				+ " AND pl.origin=origs.id"
				+ " AND origs.approvalRequired=true AND origs.approved=false ORDER BY origs.name";
		// System.out.println(sql);
		Statement s = getStatement();
		ResultSet rs = null;

		try {
			// find package lists belonging to this profile which have the
			// autoupdate flag set
			rs = s.executeQuery("SELECT pl.id FROM package_lists AS PL,profile_members AS pm"
					+ " WHERE pl.id=pm.list_id AND pm.profile_id="
					+ id
					+ "AND pl.autoupdate=true");
			// if there are any of those, no approval
			if (rs.next() != false) {
				return false;
			}
			rs.close();

			// find origin package lists which need approval and have not set
			// the
			// approval flag
			rs = s.executeQuery(sql);
			// if there are any of those, no approval
			result = rs.next() == false;
		} finally {
			releaseResultSet(rs);
			releaseStatement(s);
		}
		return result;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the alternateProfile
	 */
	public String getAlternateProfile() {
		return alternateProfile;
	}

	/**
	 * @param alternateProfile
	 *            the alternateProfile to set
	 */
	public void setAlternateProfile(String alternateProfile) {
		this.alternateProfile = alternateProfile;
	}

	/**
	 * @return the owner
	 */
	public String getOwner() {
		return owner;
	}

	/**
	 * @param owner
	 *            the owner to set
	 */
	public void setOwner(String owner) {
		this.owner = owner;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getConfigExtras() {
		return configExtras;
	}

	public void setConfigExtras(String configExtras) {
		this.configExtras = configExtras;
	}
}
