/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/

package org.apache.james.jdkim.tagvalue;

import org.apache.commons.codec.binary.Base64;
import org.apache.james.jdkim.api.SignatureRecord;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

public class SignatureRecordImpl extends TagValue implements SignatureRecord {

    // TODO ftext is defined as a sequence of at least one in %d33-57 or
    // %d59-126
    private static final Pattern hdrNamePattern = Pattern.compile("^[^: \r\n\t]+$");

    public SignatureRecordImpl(String data) {
        super(data);
    }

    protected void init() {
        mandatoryTags.add("v");
        mandatoryTags.add("a");
        mandatoryTags.add("b");
        mandatoryTags.add("bh");
        mandatoryTags.add("d");
        mandatoryTags.add("h");
        mandatoryTags.add("s");

        defaults.put("c", SIMPLE + "/" + SIMPLE);
        defaults.put("l", ALL);
        defaults.put("q", "dns/txt");
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#validate()
     */
    public void validate() throws IllegalStateException {
        super.validate();
        // TODO: what about v=0.5 and no v= at all?
        // do specs allow parsing? what should we check?
        if (!"1".equals(getValue("v")))
            throw new IllegalStateException(
                    "Invalid DKIM-Signature version (expected '1'): "
                            + getValue("v"));
        if (getValue("h").length() == 0)
            throw new IllegalStateException("Tag h= cannot be empty.");

        CharSequence identity;
        try {
            identity = getIdentity();
        } catch (IllegalArgumentException e) {
            throw new IllegalStateException("Identity (i=) declaration cannot be parsed. Probably due to missing quoted printable encoding", e);
        }

        if (!identity.toString().toLowerCase().endsWith(
                ("@" + getValue("d")).toLowerCase())
                && !getIdentity().toString().toLowerCase().endsWith(
                ("." + getValue("d")).toLowerCase()))
            throw new IllegalStateException("Identity (i=) domain mismatch: expected [optional]@[optional.]domain-from-d-attribute");

        // when "x=" exists and signature expired then return PERMFAIL
        // (signature expired)
        if (getValue("x") != null) {
            long expiration = Long.parseLong(getValue("x").toString());
            long lifetime = (expiration - System.currentTimeMillis() / 1000);
            if (lifetime < 0) {
                throw new IllegalStateException("Signature is expired since "
                        + getTimeMeasure(lifetime) + ".");
            }
        }

        // when "h=" does not contain "from" return PERMFAIL (From field not
        // signed).
        if (!isInListCaseInsensitive("from", getHeaders()))
            throw new IllegalStateException("From field not signed");
        // TODO support ignoring signature for certain d values (externally to
        // this class).
    }

    private String getTimeMeasure(long lifetime) {
        String measure = "s";
        lifetime = -lifetime;
        if (lifetime > 600) {
            lifetime = lifetime / 60;
            measure = "m";
            if (lifetime > 600) {
                lifetime = lifetime / 60;
                measure = "h";
                if (lifetime > 120) {
                    lifetime = lifetime / 24;
                    measure = "d";
                    if (lifetime > 90) {
                        lifetime = lifetime / 30;
                        measure = " months";
                        if (lifetime > 24) {
                            lifetime = lifetime / 12;
                            measure = " years";
                        }
                    }
                }
            }
        }
        return lifetime + measure;
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#getHeaders()
     */
    public List<CharSequence> getHeaders() {
        return stringToColonSeparatedList(getValue("h").toString(),
                hdrNamePattern);
    }

    // If i= is unspecified the default is @d
    protected CharSequence getDefault(String tag) {
        if ("i".equals(tag)) {
            return "@" + getValue("d");
        } else
            return super.getDefault(tag);
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#getIdentityLocalPart()
     */
    public CharSequence getIdentityLocalPart() {
        String identity = getIdentity().toString();
        int pAt = identity.indexOf('@');
        return identity.subSequence(0, pAt);
    }

    /**
     * This may throws IllegalArgumentException on invalid "i" content,
     * but should always happen during validation!
     *
     * @see org.apache.james.jdkim.api.SignatureRecord#getIdentity()
     */
    public CharSequence getIdentity() {
        return dkimQuotedPrintableDecode(getValue("i"));
    }

    public static String dkimQuotedPrintableDecode(CharSequence input)
            throws IllegalArgumentException {
        StringBuilder sb = new StringBuilder(input.length());
        // TODO should we fail on WSP that is not part of FWS?
        // the specification in 2.6 DKIM-Quoted-Printable is not
        // clear
        int state = 0;
        int start = 0;
        int d = 0;
        boolean lastWasNL = false;
        for (int i = 0; i < input.length(); i++) {
            if (lastWasNL && input.charAt(i) != ' ' && input.charAt(i) != '\t') {
                throw new IllegalArgumentException(
                        "Unexpected LF not part of an FWS");
            }
            lastWasNL = false;
            switch (state) {
                case 0:
                    switch (input.charAt(i)) {
                        case ' ':
                        case '\t':
                        case '\r':
                        case '\n':
                            if ('\n' == input.charAt(i))
                                lastWasNL = true;
                            sb.append(input.subSequence(start, i));
                            start = i + 1;
                            // ignoring whitespace by now.
                            break;
                        case '=':
                            sb.append(input.subSequence(start, i));
                            state = 1;
                            break;
                    }
                    break;
                case 1:
                case 2:
                    if (input.charAt(i) >= '0' && input.charAt(i) <= '9'
                            || input.charAt(i) >= 'A' && input.charAt(i) <= 'F') {
                        int v = Arrays.binarySearch("0123456789ABCDEF".getBytes(),
                                (byte) input.charAt(i));
                        if (state == 1) {
                            state = 2;
                            d = v;
                        } else {
                            d = d * 16 + v;
                            sb.append((char) d);
                            state = 0;
                            start = i + 1;
                        }
                    } else {
                        throw new IllegalArgumentException(
                                "Invalid input sequence at " + i);
                    }
            }
        }
        if (state != 0) {
            throw new IllegalArgumentException(
                    "Invalid quoted printable termination");
        }
        sb.append(input.subSequence(start, input.length()));
        return sb.toString();
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#getHashKeyType()
     */
    public CharSequence getHashKeyType() {
        String a = getValue("a").toString();
        int pHyphen = a.indexOf('-');
        // TODO x-sig-a-tag-h = ALPHA *(ALPHA / DIGIT)
        if (pHyphen == -1)
            throw new IllegalStateException(
                    "Invalid hash algorythm (key type): " + a);
        return a.subSequence(0, pHyphen);
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#getHashMethod()
     */
    public CharSequence getHashMethod() {
        String a = getValue("a").toString();
        int pHyphen = a.indexOf('-');
        // TODO x-sig-a-tag-h = ALPHA *(ALPHA / DIGIT)
        if (pHyphen == -1)
            throw new IllegalStateException("Invalid hash method: " + a);
        return a.subSequence(pHyphen + 1, a.length());
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#getHashAlgo()
     */
    public CharSequence getHashAlgo() {
        String a = getValue("a").toString();
        int pHyphen = a.indexOf('-');
        if (pHyphen == -1)
            throw new IllegalStateException("Invalid hash method: " + a);
        if (a.length() > pHyphen + 3 && a.charAt(pHyphen + 1) == 's'
                && a.charAt(pHyphen + 2) == 'h' && a.charAt(pHyphen + 3) == 'a') {
            return "sha-" + a.subSequence(pHyphen + 4, a.length());
        } else
            return a.subSequence(pHyphen + 1, a.length());
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#getSelector()
     */
    public CharSequence getSelector() {
        return getValue("s");
    }

    /**
     * @see org.apache.james.jdkim.api.SignatureRecord#getDToken()
     */
    public CharSequence getDToken() {
        return getValue("d");
    }

    public byte[] getBodyHash() {
        return Base64.decodeBase64(getValue("bh").toString().getBytes());
    }

    public byte[] getSignature() {
        return Base64.decodeBase64(getValue("b").toString().getBytes());
    }

    public int getBodyHashLimit() {
        String limit = getValue("l").toString();
        if (ALL.equals(limit))
            return -1;
        else
            return Integer.parseInt(limit);
    }

    public Long getSignatureTimestamp() {
        CharSequence cs = getValue("t");
        if (cs == null) return null;
        return Long.parseLong(cs.toString());
    }

    public String getBodyCanonicalisationMethod() {
        String c = getValue("c").toString();
        int pSlash = c.indexOf("/");
        if (pSlash != -1) {
            return c.substring(pSlash + 1);
        } else {
            return SIMPLE;
        }
    }

    public String getHeaderCanonicalisationMethod() {
        String c = getValue("c").toString();
        int pSlash = c.indexOf("/");
        if (pSlash != -1) {
            return c.substring(0, pSlash);
        } else {
            return c;
        }
    }

    public List<CharSequence> getRecordLookupMethods() {
        String flags = getValue("q").toString();
        String[] flagsStrings = flags.split(":");
        List<CharSequence> res = new LinkedList<CharSequence>();
        for (String flagsString : flagsStrings) {
            // TODO add validation method[/option]
            // if (VALIDATION)
            res.add(trimFWS(flagsString, 0, flagsString.length() - 1,
                    true));
        }
        return res;
    }

    public void setSignature(byte[] newSignature) {
        String signature = new String(Base64.encodeBase64(newSignature));
        setValue("b", signature);
    }

    public void setBodyHash(byte[] newBodyHash) {
        String bodyHash = new String(Base64.encodeBase64(newBodyHash));
        setValue("bh", bodyHash);
        // If a t=; parameter is present in the signature, make sure to 
        // fill it with the current timestamp
        if (getValue("t") != null && getValue("t").toString().trim().length() == 0) {
            setValue("t", "" + (System.currentTimeMillis() / 1000));
        }
    }

    public String toUnsignedString() {
        return toString().replaceFirst("b=[^;]*", "b=");
    }
}
