/*
 * Copyright (C) 2005-2006 Kouji Sugisawa. All rights reserved.
 */

package jp.sourceforge.livez.ezweb;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import jp.sourceforge.livez.IllegalUserIdException;

/**
 * SubscriberId の実装クラスです。
 * 
 * @author 杉澤 浩二
 */
final class SubscriberIdImpl implements SubscriberId {

	private static final long serialVersionUID = 1L;

	/**
	 * 文字列からこのクラスを構築するコンストラクタです。
	 * 
	 * @param subscriberId EZ番号を表す文字列
	 * @throws NullPointerException EZ番号が <code>null</code> の場合
	 * @throws IllegalArgumentException EZ番号が不正な場合
	 */
	public SubscriberIdImpl(final String subscriberId) throws NullPointerException, IllegalUserIdException {
		if (!validate(subscriberId))
			throw new IllegalUserIdException();

		this.value = subscriberId;
	}

	/**
	 * HTTP リクエスト情報からこのクラスを構築するコンストラクタです。
	 * 
	 * @param request HTTPリクエスト情報
	 * @throws NullPointerException EZ番号が見つからない場合
	 * @throws IllegalArgumentException EZ番号が不正な場合
	 */
	public SubscriberIdImpl(final HttpServletRequest request) throws NullPointerException, IllegalUserIdException {
		String subscriberId = request.getHeader("x-up-subno");

		if (!validate(subscriberId))
			throw new IllegalUserIdException();

		this.value = subscriberId;
	}

	private static boolean validate(final String subscriberId) throws NullPointerException {
		if (subscriberId == null)
			throw new NullPointerException(); 

		// 検証用正規化表現
		String key = "^" +
			// 事業者(地域)識別コード一覧
			"(" +
				"05[0-9]{2}0[0-9]{9,}" +
				"|(05[0-9]{2}[123456789](01|03|05)|(0700|0701|0702|0703|0704|0705|0706|0707|0800|0801|0802)[0-9]{3})[0-9]{7,}" +
			")" +
			// ホスト名/ドメイン名一覧
			"_(((W[23456789]\\.ez[a-z])|w0\\.upa|fwswua01\\.upb)\\.ido|([a-z]([23456789]|[a-z])|x(23469)s?|x7.xx)\\.ezweb)\\.ne\\.jp" +
			"$";

		return subscriberId.matches(key) && (subscriberId.length() <= 40);
	}

	/**
	 * EZ番号の生値を保持します。
	 */
	private String value = null;

	/*
	 * @see jp.sourceforge.livez.UserId#getValue()
	 */
	public final String getValue() {
		return value;
	}

	@Override
	public int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this);
	}

	@Override
	public boolean equals(final Object obj) {
		return EqualsBuilder.reflectionEquals(this, obj);
	}

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
	}

}
