package jp.cssj.cti.ctip.driver;

import java.io.IOException;
import java.io.OutputStream;

import jp.cssj.cti.ctip.AbstractCTIPSession;
import jp.cssj.cti.ctip.ContentProducer;
import jp.cssj.cti.helpers.ContentBuilder;
import jp.cssj.cti.helpers.FileContentBuilder;
import jp.cssj.cti.helpers.RequestConsumerOutputStream;

/**
 * @author <a href="mailto:miyabe at gnn.co.jp">MIYABE Tatsuhiko </a>
 * @version $Id: CTIPSession.java,v 1.2 2005/08/18 04:51:26 harumanx Exp $
 */
public class CTIPSession extends AbstractCTIPSession {
	protected final ContentProducerImpl producer;

	public CTIPSession(ContentProducerImpl producer, String user,
			String password) throws IOException {
		super(producer, producer.connect());
		this.producer = producer;
		CTIPRequestConsumer request = (CTIPRequestConsumer) super.request;
		request.setCTIPSession(this);

		// 認証
		request.property("ctip.auth", "PLAIN:" + user + (char) 0x0A + password);
		producer.next();
		if (producer.getType() != ContentProducer.ERROR) {
			throw new IOException("不正なレスポンスです");
		}
		String response = producer.getMessage();
		if (!response.equals("OK")) {
			throw new SecurityException("認証に失敗しました");
		}
	}

	public OutputStream sendMain(String uri, String mimeType, String encoding)
			throws IOException {
		if (this.state >= 2) {
			throw new IllegalStateException("既に本体が変換されています。");
		}
		this.request.main(uri, mimeType, encoding);
		this.state = 2;
		return new RequestConsumerOutputStream(this.request) {
			public void close() throws IOException {
				CTIPSession.this.request.end();
				CTIPSession.this.state = 3;
			}
		};
	}

	public void close() throws IOException {
		if (this.state >= 3) {
			return;
		}
		this.producer.close();
		this.state = 3;
	}

	protected ContentBuilder createContentBuilder() throws IOException {
		return new FileContentBuilder(this.out);
	}

	protected void finishBuild(ContentBuilder builder) throws IOException {
		while (this.buildNext(builder)) {
			// do nothing
		}
		if (this.progressListener != null
				&& this.progressListener.requiresContentLength()) {
			this.progressListener.contentLength(((FileContentBuilder) builder)
					.getLength());
		}
	}
}