
package org.pircbotx.cap;

import com.google.common.collect.ImmutableList;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.pircbotx.PircBotX;
import org.pircbotx.exception.CAPException;

/**
 * Enables the specified capability with the server. This handler should cover
 * almost all CAP features except SASL since most only need to be requested.
 *
 * @author Leon Blakey
 */
@Slf4j
@RequiredArgsConstructor
@ToString
public class EnableCapHandler implements CapHandler {
	@Getter
	protected final String cap;
	protected final boolean ignoreFail;

	/**
	 * Create EnableCapHandler not ignoring if server doesn't support the
	 * requested capability
	 */
	public EnableCapHandler(String cap) {
		this.cap = cap;
		this.ignoreFail = false;
	}

	@Override
	public boolean handleLS(PircBotX bot, ImmutableList<String> capabilities) throws CAPException {
		if (capabilities.contains(cap)) {
			//Server supports capability, send request to use it
			log.debug("Supported capability " + cap);
			bot.sendCAP().request(cap);
			//Need to wait for server ACK
			return false;
		} else if (!ignoreFail)
			throw new CAPException(CAPException.Reason.UnsupportedCapability, cap);
		else {
			//Server doesn't support capability but were ignoring exceptions
			log.debug("Unsupported capability " + cap);
			return true;
		}
	}

	@Override
	public boolean handleACK(PircBotX bot, ImmutableList<String> capabilities) throws CAPException {
		//Finished if the server is acknowledging the capability
		return capabilities.contains(cap);
	}

	@Override
	public boolean handleNAK(PircBotX bot, ImmutableList<String> capabilities) throws CAPException {
		if (capabilities.contains(cap)) {
			//Make sure the bot didn't register this capability
			bot.getEnabledCapabilities().remove(cap);
			if (!ignoreFail)
				throw new CAPException(CAPException.Reason.UnsupportedCapability, cap);
			else
				//Nothing more to do
				return true;
		}
		//Not applicable to us
		return false;
	}

	@Override
	public boolean handleUnknown(PircBotX bot, String rawLine) {
		return false;
	}
}
