package jp.sourceforge.shovel.util;

import static java.util.Locale.ENGLISH;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jp.sourceforge.shovel.exception.ApplicationException;

public class ShovelUtil {
    static public final int VALIDATION          = 0;
    static public final int EMPTY_DISPLAYNAME   = 1;
    static public final int EMPTY_FOREIGNKEY    = 2;
    static public final int PROHIBIT_CHAR       = 3;
    static public final int PROHIBIT_SUFFIX     = 4;
    static public final int RESERVED_FOREINGKEY = 5;
    static public final int INVALID_EMAIL       = 6;
    
    static final String emailPattern_ = "^[^@]+@[^.]+\\..+";
    static final String prohibitChar_ = "[^\\w\\.\\=]";
    static final String prohibitSuffix_ = "(\\.(atom|do|ftl|json|rss|xml))$";
    static final String reservedFK_ = "^(login|logout|home|replies|public_timeline|friends|followers|friend_requests|favorites|device|system)$";
    
    public static int validateUser(String displayName, String foreignKey, String email, boolean retval) throws ApplicationException {
        //スクリーン名
        if (displayName != null) {
            displayName = displayName.trim();
            if (displayName.length() <= 0) {
                if (retval) {
                    return EMPTY_DISPLAYNAME;
                }
                throw new ApplicationException("");
            }
        }
        //アカウント名
        if (foreignKey != null) {
            foreignKey = foreignKey.trim();
            if (foreignKey.length() <= 0) {
                if (retval) {
                    return EMPTY_FOREIGNKEY;
                }
                throw new ApplicationException("");
            }
            Pattern pattern = Pattern.compile(prohibitChar_);
            Matcher matcher = pattern.matcher(foreignKey);
            if (matcher.find()) {
                if (retval) {
                    return PROHIBIT_CHAR;
                }
                throw new ApplicationException("");
            }
            pattern = Pattern.compile(prohibitSuffix_);
            matcher = pattern.matcher(foreignKey);
            if (matcher.find()) {
                if (retval) {
                    return PROHIBIT_SUFFIX;
                }
                throw new ApplicationException("");
            }
            pattern = Pattern.compile(reservedFK_);
            matcher = pattern.matcher(foreignKey);
            if (matcher.find()) {
                if (retval) {
                    return RESERVED_FOREINGKEY;
                }
                throw new ApplicationException("");
            }
        }
        //Email
        if (email != null) {
            email = email.trim();
            if (email.length() > 0 && !email.matches(emailPattern_)) {
                if (retval) {
                    return INVALID_EMAIL;
                }
                throw new ApplicationException("");
            }
        }
        return VALIDATION;
    }
    public static String escape(String param) {
        StringBuilder escaped = new StringBuilder();
        for (int i = 0; i < param.length(); i++) {
            String ch = param.substring(i, i + 1);
            if (ch.compareTo("%") == 0 || ch.compareTo("_") == 0) {
                escaped.append("\\");
            }
            escaped.append(ch);
        }
        return escaped.toString();
    }
    public static long parseRFC2822DateTime(String since) throws ApplicationException {
        try {
            DateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", ENGLISH);
            Date date = format.parse(since);
            return date.getTime();
        } catch (ParseException e) {
            throw new ApplicationException("");
        }
    }
    public static String generateToken(String dataString) throws ApplicationException {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] data = dataString.getBytes();
            md.update(data, 0, data.length);

            StringBuilder builder = new StringBuilder();
            byte[] digest = md.digest();
            for (int i = 0; i < digest.length; i++) {
                int d = digest[i];
                if (d < 0) {
                    d += 256;
                }
                if (d < 16) {
                    builder.append("0");
                }
                builder.append(Integer.toString(d, 16));
            }
            return builder.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new ApplicationException("");
        }
    }
}
