/**
 * Copyright (c) 2006, yher2.net
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice, 
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice, 
 *   this list of conditions and the following disclaimer in the documentation 
 *   and/or other materials provided with the distribution.
 * * Neither the name of the nor the names of its contributors may be used to endorse or 
 *   promote products derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 * SUCH DAMAGE.
 */
package net.yher2.workstyle.manager;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import net.yher2.workstyle.exception.NotFoundException;
import net.yher2.workstyle.torque.Tag;
import net.yher2.workstyle.torque.TagPeer;
import net.yher2.workstyle.torque.TagType;
import net.yher2.workstyle.torque.TagTypePeer;
import net.yher2.workstyle.torque.Task;
import net.yher2.workstyle.torque.TaskPeer;
import net.yher2.workstyle.torque.bean.TagBean;

import org.apache.torque.NoRowsException;
import org.apache.torque.TorqueException;
import org.apache.torque.util.Criteria;

public class TagManager {
	private Connection con = null;
	
	public TagManager(Connection con) {
		this.con = con;
	}
	protected void add(String tag) throws TorqueException {
		List<String> tagList = new ArrayList<String>();
		tagList.add(tag);
		add(tagList);
	}
	protected void add(List<String> tagList) throws TorqueException {
		if (tagList.size() == 0) return;
		List<Tag> dbTagList = TagPeer.doSelectByName(tagList, con);
		for (Tag tag : dbTagList) {
			tagList.remove(tag.getName());
		}
		for (String tagName : tagList) {
			Tag dbTag = new Tag();
			dbTag.setActive(Tag.ACTIVE);
			dbTag.setName(tagName);
			dbTag.setTagTypeId(TagType.DEFAULT_ID);
			
			TagPeer.doInsert(dbTag, con);
		}
	}
	
	public void updateType(int tagId, int tagTypeId) throws TorqueException, NotFoundException {
		Tag tag = getDBModel(tagId);
		TagType tagType = new TagTypeManager(con).getDBModel(tagTypeId);
		
		tag.setTagTypeId(tagType.getTagTypeId());
		TagPeer.doUpdate(tag, con);
	}
	
	public void activate(int tagId) throws TorqueException, NotFoundException {
		updateActiveStatus(tagId, Tag.ACTIVE);
	}
	public void inactivate(int tagId) throws TorqueException, NotFoundException {
		updateActiveStatus(tagId, Tag.INACTIVE);
	}
	
	private void updateActiveStatus(int tagId, short isActive) throws TorqueException, NotFoundException {
		Tag tag = getDBModel(tagId);
		tag.setActive(isActive);
		TagPeer.doUpdate(tag, con);
	}
	
	public List<TagBean> list() throws TorqueException {
		Criteria criteria = new Criteria();
		criteria.addJoin(TagPeer.TAG_TYPE_ID, TagTypePeer.TAG_TYPE_ID);
		criteria.add(TagPeer.ACTIVE, Tag.ACTIVE);
		criteria.addAscendingOrderByColumn(TagTypePeer.SORT_ORDER);
		criteria.addAscendingOrderByColumn(TagPeer.NAME);
		
		return list(criteria);
	}
	public List<TagBean> listAll() throws TorqueException {
		Criteria criteria = new Criteria();
		criteria.addJoin(TagPeer.TAG_TYPE_ID, TagTypePeer.TAG_TYPE_ID);
		criteria.addAscendingOrderByColumn(TagTypePeer.SORT_ORDER);
		criteria.addAscendingOrderByColumn(TagPeer.NAME);
		
		return list(criteria);
	}
	private List<TagBean> list(Criteria criteria) throws TorqueException {
		List<Tag> dbTagList = TagPeer.doSelectJoinTagType(criteria, con);
		List<TagBean> beanList = new ArrayList<TagBean>();
		for (Tag tag : dbTagList) {
			beanList.add(tag.getBean());
		}
		return beanList;
	}
	
	public TagBean delete(int tagId) throws TorqueException, NotFoundException {
		Tag tag = getDBModel(tagId);
		
		Criteria criteria = new Criteria();
		String tagKey = "%" + Tag.format(tag.getName()) + "%";
		criteria.add(TaskPeer.TAG_LIST, (Object)tagKey, Criteria.LIKE);
		List<Task> taskList = TaskPeer.doSelect(criteria, con);
		
		tagKey = Tag.formatRegExp(tag.getName());
		for (Task task : taskList) {
			task.setTagList(task.getTagList().replaceAll(tagKey, ""));
			TaskPeer.doUpdate(task, con);
		}
		TagPeer.doDelete(tag.getPrimaryKey(), con);
		return tag.getBean();
	}
	private Tag getDBModel(int tagId) throws TorqueException, NotFoundException {
		try {
			return TagPeer.retrieveByPK(tagId, con);
		} catch (NoRowsException e) {
			throw new NotFoundException("指定のタグ("+tagId+")");
		}
	}
}
