/****************************************************************
 * 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.mime4j.utils.search;

import com.google.common.collect.ImmutableList;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.stream.EntityState;
import org.apache.james.mime4j.stream.MimeConfig;
import org.apache.james.mime4j.stream.MimeTokenStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.nio.CharBuffer;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;

/**
 * Searches an email for content.
 */
public class MessageMatcher {

    public static class MessageMatcherBuilder {

        private List<CharSequence> searchContents;
        private List<String> contentTypes;
        private boolean isCaseInsensitive;
        private boolean includeHeaders;
        private boolean ignoringMime;
        private Logger logger;

        public MessageMatcherBuilder() {
            this.searchContents = ImmutableList.of();
            this.contentTypes = ImmutableList.of();
            this.isCaseInsensitive = false;
            this.includeHeaders = false;
            this.ignoringMime = false;
            this.logger = LoggerFactory.getLogger(MessageMatcher.class);
        }

        public MessageMatcherBuilder searchContents(List<CharSequence> searchContents) {
            this.searchContents = searchContents;
            return this;
        }

        public MessageMatcherBuilder contentTypes(List<String> contentTypes) {
            this.contentTypes = contentTypes;
            return this;
        }

        public MessageMatcherBuilder caseInsensitive(boolean isCaseInsensitive) {
            this.isCaseInsensitive = isCaseInsensitive;
            return this;
        }

        public MessageMatcherBuilder includeHeaders(boolean includeHeaders) {
            this.includeHeaders = includeHeaders;
            return this;
        }

        public MessageMatcherBuilder logger(Logger logger) {
            this.logger = logger;
            return this;
        }

        public MessageMatcherBuilder ignoringMime(boolean ignoringMime) {
            this.ignoringMime = ignoringMime;
            return this;
        }

        public MessageMatcher build() {
            return new MessageMatcher(searchContents, isCaseInsensitive, includeHeaders, ignoringMime, contentTypes, logger);
        }

    }

    public static MessageMatcherBuilder builder() {
        return new MessageMatcherBuilder();
    }

    private final Logger logger;
    private final List<CharSequence> searchContents;
    private final List<String> contentTypes;
    private final boolean isCaseInsensitive;
    private final boolean includeHeaders;
    private final boolean ignoringMime;

    private MessageMatcher(List<CharSequence> searchContents, boolean isCaseInsensitive, boolean includeHeaders,
                           boolean ignoringMime, List<String> contentTypes, Logger logger) {
        this.contentTypes = ImmutableList.copyOf(contentTypes);
        this.searchContents = ImmutableList.copyOf(searchContents);
        this.isCaseInsensitive = isCaseInsensitive;
        this.includeHeaders = includeHeaders;
        this.ignoringMime = ignoringMime;
        this.logger = logger;
    }

    /**
     * Is searchContents found in the given input?
     *
     * @param input
     *            <code>InputStream</code> containing an email
     * @return true if the content exists and the stream contains the content,
     *         false otherwise. It takes the mime structure into account.
     * @throws IOException
     * @throws MimeException
     */
    public boolean messageMatches(final InputStream input) throws IOException, MimeException {
        for (CharSequence charSequence : searchContents) {
            if (charSequence != null) {
                final CharBuffer buffer = createBuffer(charSequence);
                if (ignoringMime) {
                    if (! isFoundIn(new InputStreamReader(input), buffer)) {
                        return false;
                    }
                } else {
                    if (!matchBufferInMailBeingMimeAware(input, buffer)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private boolean matchBufferInMailBeingMimeAware(final InputStream input, final CharBuffer buffer) throws IOException, MimeException {
        try {
            MimeConfig config = MimeConfig.custom().setMaxLineLen(-1).setMaxHeaderLen(-1).build();

            MimeTokenStream parser = new MimeTokenStream(config);
            parser.parse(input);
            while (parser.next() != EntityState.T_END_OF_STREAM) {
                final EntityState state = parser.getState();
                switch (state) {
                    case T_PREAMBLE:
                    case T_EPILOGUE:
                    case T_BODY:
                        if (contentTypes.isEmpty() || contentTypes.contains(parser.getBodyDescriptor().getMimeType())) {
                            if (checkBody(buffer, parser)) {
                                return true;
                            }
                        }
                        break;
                    case T_FIELD:
                        if (includeHeaders) {
                            if (checkHeader(buffer, parser)) {
                                return true;
                            }
                        }
                        break;
                case T_END_BODYPART:
                case T_END_HEADER:
                case T_END_MESSAGE:
                case T_END_MULTIPART:
                case T_END_OF_STREAM:
                case T_RAW_ENTITY:
                case T_START_BODYPART:
                case T_START_HEADER:
                case T_START_MESSAGE:
                case T_START_MULTIPART:
                    break;
                }
            }
        } catch (IllegalCharsetNameException e) {
            handle(e);
        } catch (UnsupportedCharsetException e) {
            handle(e);
        } catch (IllegalStateException e) {
            handle(e);
        }
        return false;
    }

    private boolean checkHeader(final CharBuffer buffer, MimeTokenStream parser) throws IOException {
        final String value = parser.getField().getBody();
        final StringReader reader = new StringReader(value);
        return isFoundIn(reader, buffer);
    }

    private boolean checkBody(final CharBuffer buffer, MimeTokenStream parser) throws IOException {
        final Reader reader = parser.getReader();
        return isFoundIn(reader, buffer);
    }

    private CharBuffer createBuffer(final CharSequence searchContent) {
        final CharBuffer buffer;
        if (isCaseInsensitive) {
            final int length = searchContent.length();
            buffer = CharBuffer.allocate(length);
            for (int i = 0; i < length; i++) {
                final char next = searchContent.charAt(i);
                final char upperCase = Character.toUpperCase(next);
                buffer.put(upperCase);
            }
            buffer.flip();
        } else {
            buffer = CharBuffer.wrap(searchContent);
        }
        return buffer;
    }

    protected void handle(Exception e) throws IOException, MimeException {
        logger.warn("Cannot read MIME body.");
        logger.debug("Failed to read body.", e);
    }

    public boolean isFoundIn(final Reader reader, final CharBuffer buffer) throws IOException {
        int read;
        while ((read = reader.read()) != -1) {
            if (matches(buffer, computeNextChar(isCaseInsensitive, (char) read))) {
                return true;
            }
        }
        return false;
    }

    private char computeNextChar(boolean isCaseInsensitive, char read) {
        if (isCaseInsensitive) {
            return Character.toUpperCase(read);
        } else {
            return read;
        }
    }

    private boolean matches(final CharBuffer buffer, final char next) {
        if (buffer.hasRemaining()) {
            final boolean partialMatch = (buffer.position() > 0);
            final char matching = buffer.get();
            if (next != matching) {
                buffer.rewind();
                if (partialMatch) {
                    return matches(buffer, next);
                }
            }
        } else {
            return true;
        }
        return false;
    }

}
