package hiro.yoshioka.sql.resource.twitter;

import hiro.yoshioka.sql.resource.DBColumn.SearchableType;
import hiro.yoshioka.sql.resource.DBRoot;
import hiro.yoshioka.util.StringUtil;

import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public enum TwitterColumnType {
	// --------------------------------------------------------------------------
	// SEARCH PARAMS
	// --------------------------------------------------------------------------
	/** limitNum */
	limitNum("limitNum", Types.NUMERIC, "LONG", "none"),
	/** whomUserId */
	whomUserId("whomUserId", Types.NUMERIC, "LONG", "none"),
	/** exclude */
	exclude("exclude", Types.BOOLEAN, "BOOLEAN", "none"),
	/** date */
	date("date", Types.DATE, "DATE", "none"),
	/** search_query */
	search_query("search_query", Types.VARCHAR, "VARCHAR", "none"),
	// --------------------------------------------------------------------------
	// ETC
	// --------------------------------------------------------------------------
	/** sleepStartTime */
	sleepStartTime("sleepStartTime", Types.VARCHAR, "VARCHAR",
			"getSleepStartTime"),
	/** sleepEndTime */
	sleepEndTime("sleepEndTime", Types.VARCHAR, "VARCHAR", "getSleepEndTime"),
	/** trendLocations */
	trendLocations("trendLocations", Types.VARCHAR, "VARCHAR",
			"getTrendLocations"),
	/** geoEnabled */
	geoEnabled("geoEnabled", Types.BOOLEAN, "BOOLEAN", "isGeoEnabled"),
	/** sleepTimeEnabled */
	sleepTimeEnabled("sleepTimeEnabled", Types.BOOLEAN, "BOOLEAN",
			"isSleepTimeEnabled"),

	/** updates */
	updates("updates", Types.INTEGER, "INTEGER", "getUpdates"),
	/** followers */
	followers("followers", Types.INTEGER, "INTEGER", "getFollowers"),
	/** favorites */
	favorites("favorites", Types.INTEGER, "INTEGER", "getFavorites"),
	/** friends */
	friends("friends", Types.INTEGER, "INTEGER", "getFriends"),

	/** name */
	name("name", Types.VARCHAR, "VARCHAR", "getName"),
	/** url */
	url("url", Types.VARCHAR, "VARCHAR", "getUrl"),
	/** query */
	query("query", Types.VARCHAR, "VARCHAR", "getQuery"),
	/** trendAt */
	trendAt("trendAt", Types.DATE, "DATE", "getTrendAt"),

	/** createdAt */
	createdAt("createdAt", Types.DATE, "DATE", "getCreatedAt"),
	/** id */
	id("id", Types.VARCHAR, "VARCHAR", "getId", true),
	/** text */
	text("text", Types.LONGVARCHAR, "LONGVARCHAR", "getText"),
	/** source */
	source("source", Types.VARCHAR, "VARCHAR", "getSource"),
	/** isTruncated */
	isTruncated("isTruncated", Types.BOOLEAN, "BOOLEAN", "isTruncated"),
	/** inReplyToStatusId */
	inReplyToStatusId("inReplyToStatusId", Types.NUMERIC, "LONG",
			"getInReplyToStatusId"),
	/** inReplyToUserId */
	inReplyToUserId("inReplyToUserId", Types.NUMERIC, "LONG",
			"getInReplyToUserId"),
	/** isFavorited */
	isFavorited("isFavorited", Types.BOOLEAN, "BOOLEAN", "isFavorited"),
	/** inReplyToScreenName */
	inReplyToScreenName("inReplyToScreenName", Types.VARCHAR, "VARCHAR",
			"getInReplyToScreenName"),
	/** place */
	place("place", Types.VARCHAR, "VARCHAR", "getPlace"),
	/** retweetCount */
	retweetCount("retweetCount", Types.NUMERIC, "LONG", "getRetweetCount"),
	/** wasRetweetedByMe */
	wasRetweetedByMe("wasRetweetedByMe", Types.BOOLEAN, "BOOLEAN",
			"isRetweetedByMe"),
	/** contributors */
	contributors("contributors", Types.VARCHAR, "VARCHAR", "getContributors"),
	/** annotations */
	annotations("annotations", Types.VARCHAR, "VARCHAR", "getAnnotations"),
	/** retweetedStatus */
	retweetedStatus("retweetedStatus", Types.STRUCT, "STRUCT",
			"getRetweetedStatus"),
	/** userMentionEntities */
	userMentionEntities("userMentionEntities", Types.STRUCT, "STRUCT",
			"getUserMentionEntities"),
	/** urlEntities */
	urlEntities("urlEntities", Types.STRUCT, "STRUCT", "getURLEntities"),
	// --------------------------------------------------------------------------
	// DIRECT MESSSAGES
	// --------------------------------------------------------------------------
	/** createAt */
	createAt("createAt", Types.DATE, "DATE", "getCreatedAt"),
	// id
	/** recipient */
	recipient("recipient", Types.LONGVARCHAR, "LONGVARCHAR", "getRecipient"),
	/** recipientId */
	recipientId("recipientId", Types.NUMERIC, "LONG", "getRecipientId"),
	/** recipientScreenName */
	recipientScreenName("recipientScreenName", Types.VARCHAR, "VARCHAR",
			"getRecipientScreenName"),
	/** sender */
	sender("sender", Types.LONGVARCHAR, "LONGVARCHAR", "getSender"),
	/** senderId */
	senderId("senderId", Types.NUMERIC, "LONG", "getSenderId"),
	/** senderScreenName */
	senderScreenName("senderScreenName", Types.VARCHAR, "VARCHAR",
			"getSenderScreenName"),
	// text
	// --------------------------------------------------------------------------
	// USER
	// --------------------------------------------------------------------------
	// createdAt
	/** description */
	description("description", Types.VARCHAR, "VARCHAR", "getDescription"),
	/** favouritesCount */
	favouritesCount("favouritesCount", Types.INTEGER, "INTEGER",
			"getFavouritesCount"),
	/** followersCount */
	followersCount("followersCount", Types.INTEGER, "INTEGER",
			"getFollowersCount"),
	/** friendsCount */
	friendsCount("friendsCount", Types.INTEGER, "INTEGER", "getFriendsCount"),
	// id
	/** lang */
	lang("lang", Types.VARCHAR, "VARCHAR", "getLang"),
	/** listedCount */
	listedCount("listedCount", Types.INTEGER, "INTEGER", "getListedCount"),
	/** location */
	location("location", Types.VARCHAR, "VARCHAR", "getLocation"),
	// name
	/** profileBackgroundColor */
	profileBackgroundColor("profileBackgroundColor", Types.VARCHAR, "VARCHAR",
			"getProfileBackgroundColor"),
	/** profileBackgroundImageUrl */
	profileBackgroundImageUrl("profileBackgroundImageUrl", Types.VARCHAR,
			"VARCHAR", "getProfileBackgroundImageUrl"),
	/** profileBackgroundImageUrlHttps */
	profileBackgroundImageUrlHttps("profileBackgroundImageUrlHttps",
			Types.VARCHAR, "VARCHAR", "getProfileBackgroundImageUrlHttps"),
	/** profileImageURL */
	profileImageURL("profileImageURL", Types.VARCHAR, "VARCHAR",
			"getProfileImageURL"),
	/** profileImageUrlHttps */
	profileImageUrlHttps("profileImageUrlHttps", Types.VARCHAR, "VARCHAR",
			"getProfileImageUrlHttps"),
	/** profileLinkColor */
	profileLinkColor("profileLinkColor", Types.VARCHAR, "VARCHAR",
			"getProfileLinkColor"),
	/** profileSidebarBorderColor */
	profileSidebarBorderColor("profileSidebarBorderColor", Types.VARCHAR,
			"VARCHAR", "getProfileSidebarBorderColor"),
	/** profileSidebarFillColor */
	profileSidebarFillColor("profileSidebarFillColor", Types.VARCHAR,
			"VARCHAR", "getProfileSidebarFillColor"),
	/** profileTextColor */
	profileTextColor("profileTextColor", Types.VARCHAR, "VARCHAR",
			"getProfileTextColor"),
	/** screenName */
	screenName("screenName", Types.VARCHAR, "VARCHAR", "getScreenName"),
	/** status */
	status("status", Types.LONGVARCHAR, "LONGVARCHAR", "getStatus"),
	/** statusesCount */
	statusesCount("statusesCount", Types.INTEGER, "INTEGER", "getStatusesCount"),
	// --------------------------------------------------------------------------
	// LOCATION
	// --------------------------------------------------------------------------
	/** woeid */
	woeid("woeid", Types.INTEGER, "INTEGER", "getWoeid"),
	/** countryName */
	countryName("countryName", Types.VARCHAR, "VARCHAR", "getCountryName"),
	/** countryCode */
	countryCode("countryCode", Types.VARCHAR, "VARCHAR", "getCountryCode"),
	/** placeName */
	placeName("placeName", Types.VARCHAR, "VARCHAR", "getPlaceName"),
	/** placeCode */
	placeCode("placeCode", Types.INTEGER, "INTEGER", "getPlaceCode");
	// name
	// url

	public static final List<TwitterColumnType> ACCOUNT_SETTINGS_LIST = new ArrayList<TwitterColumnType>();
	public static final List<TwitterColumnType> ACCOUNT_TOTALS = new ArrayList<TwitterColumnType>();
	public static final List<TwitterColumnType> TREND_LIST = new ArrayList<TwitterColumnType>();
	public static final List<TwitterColumnType> TIMELINE_LIST = new ArrayList<TwitterColumnType>();
	public static final List<TwitterColumnType> DIRECT_MESSAGE_LIST = new ArrayList<TwitterColumnType>();
	public static final List<TwitterColumnType> USER_LIST = new ArrayList<TwitterColumnType>();
	public static final List<TwitterColumnType> LOCATION_LIST = new ArrayList<TwitterColumnType>();

	static {
		ACCOUNT_SETTINGS_LIST.add(sleepStartTime);
		ACCOUNT_SETTINGS_LIST.add(sleepEndTime);
		ACCOUNT_SETTINGS_LIST.add(trendLocations);
		ACCOUNT_SETTINGS_LIST.add(geoEnabled);
		ACCOUNT_SETTINGS_LIST.add(sleepTimeEnabled);

		ACCOUNT_TOTALS.add(updates);
		ACCOUNT_TOTALS.add(followers);
		ACCOUNT_TOTALS.add(favorites);
		ACCOUNT_TOTALS.add(friends);

		TREND_LIST.add(name);
		TREND_LIST.add(url);
		TREND_LIST.add(query);

		TIMELINE_LIST.add(createdAt);
		TIMELINE_LIST.add(id);
		TIMELINE_LIST.add(text);
		TIMELINE_LIST.add(source);
		TIMELINE_LIST.add(isTruncated);
		TIMELINE_LIST.add(inReplyToStatusId);
		TIMELINE_LIST.add(inReplyToUserId);
		TIMELINE_LIST.add(isFavorited);
		TIMELINE_LIST.add(inReplyToScreenName);
		TIMELINE_LIST.add(place);
		TIMELINE_LIST.add(retweetCount);
		TIMELINE_LIST.add(wasRetweetedByMe);
		TIMELINE_LIST.add(contributors);
		TIMELINE_LIST.add(annotations);
		TIMELINE_LIST.add(retweetedStatus);
		TIMELINE_LIST.add(userMentionEntities);
		TIMELINE_LIST.add(urlEntities);

		DIRECT_MESSAGE_LIST.add(createAt);
		DIRECT_MESSAGE_LIST.add(id);
		DIRECT_MESSAGE_LIST.add(recipient);
		DIRECT_MESSAGE_LIST.add(recipientId);
		DIRECT_MESSAGE_LIST.add(recipientScreenName);
		DIRECT_MESSAGE_LIST.add(sender);
		DIRECT_MESSAGE_LIST.add(senderId);
		DIRECT_MESSAGE_LIST.add(senderScreenName);
		DIRECT_MESSAGE_LIST.add(text);

		USER_LIST.add(createdAt);
		USER_LIST.add(description);
		USER_LIST.add(favouritesCount);
		USER_LIST.add(followersCount);
		USER_LIST.add(friendsCount);
		USER_LIST.add(id);
		USER_LIST.add(lang);
		USER_LIST.add(listedCount);
		USER_LIST.add(location);
		USER_LIST.add(name);
		USER_LIST.add(profileBackgroundColor);
		USER_LIST.add(profileBackgroundImageUrl);
		USER_LIST.add(profileBackgroundImageUrlHttps);
		USER_LIST.add(profileImageURL);
		USER_LIST.add(profileImageUrlHttps);
		USER_LIST.add(profileLinkColor);
		USER_LIST.add(profileSidebarBorderColor);
		USER_LIST.add(profileSidebarFillColor);
		USER_LIST.add(profileTextColor);
		USER_LIST.add(screenName);
		USER_LIST.add(status);
		USER_LIST.add(statusesCount);

		LOCATION_LIST.add(woeid);
		LOCATION_LIST.add(countryName);
		LOCATION_LIST.add(countryCode);
		LOCATION_LIST.add(placeName);
		LOCATION_LIST.add(placeCode);
		LOCATION_LIST.add(name);
		LOCATION_LIST.add(url);
	}
	private String columnName;
	private int columnType;
	private String dataTypeString;
	private String valueMethod;
	private boolean primaryKey;

	private TwitterColumnType(String columnName, int dataType,
			String dataTypeString, String valueMethod) {
		this(columnName, dataType, dataTypeString, valueMethod, false);
	}

	private TwitterColumnType(String columnName, int dataType,
			String dataTypeString, String valueMethod, boolean primaryKey) {
		this.columnName = columnName;
		this.columnType = dataType;
		this.dataTypeString = dataTypeString;
		this.valueMethod = valueMethod;
		this.primaryKey = primaryKey;
	}

	public boolean isPrimaryKey() {
		return primaryKey;
	}

	public String getColumnName() {
		return columnName;
	}

	public int getColumnType() {
		return columnType;
	}

	public String getDataTypeString() {
		return dataTypeString;
	}

	public String getValueMethod() {
		return valueMethod;
	}

	public boolean isOnClickable() {
		switch (this) {
		case profileBackgroundImageUrl:
		case profileBackgroundImageUrlHttps:
		case profileImageURL:
		case profileImageUrlHttps:
		case source:
		case url:
			return true;

		}
		return false;
	}

	public static List<TwitterColumnType> getColumnTypeListOf(
			TwitterSchemaType schemaType, TwitterTableType tableType) {
		switch (schemaType) {
		case Account:
			switch (tableType) {
			case AccountSettings:
				return ACCOUNT_SETTINGS_LIST;
			case AccountTotals:
				return ACCOUNT_TOTALS;
			}
			break;
		case LocalTrends:
			switch (tableType) {
			case AvailableTrends:
				return LOCATION_LIST;
			}
			return TREND_LIST;
		case Timeline:
			return TIMELINE_LIST;
		case DirectMessage:
			return DIRECT_MESSAGE_LIST;
		case User:
			return USER_LIST;
		case Followers:
			return USER_LIST;
		}
		return Collections.EMPTY_LIST;
	}

	public SearchableType getSearchableType(TwitterTableType tableType) {
		switch (this) {
		case id:
			if (TwitterTableType.LookupUsers.equals(tableType)
					|| TwitterTableType.ShowUser.equals(tableType)) {
				return SearchableType.SEARCHABLE_VISIBLE;
			}
			break;
		case name:
		case screenName:
			if (TwitterTableType.LookupUsers.equals(tableType)
					|| TwitterTableType.ShowUser.equals(tableType)) {
				return SearchableType.SEARCHABLE_VISIBLE;
			}
			break;
		case woeid:
		case exclude:
		case whomUserId:
		case search_query:
		case date:
			return SearchableType.SEARCHABLE_VISIBLE;
		}
		return SearchableType.UNSEARCHABLE;
	}

	public static List<TwitterColumnType> getSearchColumnTypeListOf(
			TwitterSchemaType schemaType, TwitterTableType tableType) {
		List<TwitterColumnType> retList;
		switch (schemaType) {
		case Account:
			return Collections.EMPTY_LIST;
		case LocalTrends:
			switch (tableType) {
			case LocationTrends:
				retList = new ArrayList<TwitterColumnType>();
				retList.add(woeid);
				return retList;
			}
			break;
		case Timeline:
			switch (tableType) {
			case RetweetedByUser:
			case RetweetedToUser:
				retList = new ArrayList<TwitterColumnType>();
				retList.add(whomUserId);
				return retList;
			}
			break;
		case DirectMessage:
			break;
		case User:
			switch (tableType) {
			case SearchUsers:
				retList = new ArrayList<TwitterColumnType>();
				retList.add(search_query);
				return retList;
			}
			break;
		case Followers:
			retList = new ArrayList<TwitterColumnType>();
			retList.add(whomUserId);
			return retList;
		}
		return Collections.EMPTY_LIST;
	}

	public String getDefaultValue(DBRoot root, TwitterSchemaType schemaType,
			TwitterTableType tableType) {
		switch (schemaType) {
		case LocalTrends:
			// case Trends:
			switch (tableType) {
			case LocationTrends:
				switch (this) {
				case woeid:
					return "23424856";
				}
				break;
			}
			break;
		case Timeline:
			switch (tableType) {
			case RetweetedByUser:
			case RetweetedToUser:
				switch (this) {
				case whomUserId:
					return root.getPropertyValue(whomUserId.name());
				}
			}
			break;
		case DirectMessage:
			break;
		case Followers:
			switch (this) {
			case whomUserId:
				return root.getPropertyValue(whomUserId.name());
			}
		case User:
			switch (tableType) {
			case ShowUser:
			case LookupUsers:
				switch (this) {
				case id:
					return root.getPropertyValue(whomUserId.name());
				}
			case SearchUsers:
				switch (this) {
				case search_query:
					return "<SEARCH_WORDS>";
				}
			}
			break;
		}
		return StringUtil.EMPTY_STRING;
	}

}
