/****************************************************************
 * 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.jmap.model;

import java.util.Arrays;
import java.util.Collection;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;

import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

public class MessageProperties {

    public static final ImmutableSet<MessageProperty> MANDATORY_PROPERTIES = ImmutableSet.of(MessageProperty.id);

    private final Optional<ImmutableSet<MessageProperty>> messageProperties;
    private final Optional<ImmutableSet<HeaderProperty>> headersProperties;

    public MessageProperties(Optional<ImmutableSet<String>> properties) {
        this.messageProperties = properties.map(this::toMessageProperties);
        this.headersProperties = properties.map(this::toHeadersProperties);
    }

    private MessageProperties(Optional<ImmutableSet<MessageProperty>> messageProperties,
                              Optional<ImmutableSet<HeaderProperty>> headersProperties) {
        this.messageProperties = messageProperties;
        this.headersProperties = headersProperties;
    }

    private ImmutableSet<MessageProperty> toMessageProperties(ImmutableSet<String> properties) {
        return properties.stream().flatMap(MessageProperty::find).collect(ImmutableSet.toImmutableSet());
    }

    private ImmutableSet<HeaderProperty> toHeadersProperties(ImmutableSet<String> properties) {
        return properties.stream().flatMap(HeaderProperty::find).collect(ImmutableSet.toImmutableSet());
    }

    public Optional<ImmutableSet<HeaderProperty>> getOptionalHeadersProperties() {
        return headersProperties;
    }

    public Optional<ImmutableSet<MessageProperty>> getOptionalMessageProperties() {
        return messageProperties;
    }

    public MessageProperties toOutputProperties() {
        return this.ensureContains(MANDATORY_PROPERTIES)
                .selectBody()
                .overrideHeadersFilteringOnHeadersMessageProperty()
                .ensureHeadersMessageProperty();
    }

    public ReadProfile computeReadLevel() {
        Stream<ReadProfile> readLevels = Stream.concat(this.buildOutputMessageProperties()
                .stream()
                .map(MessageProperty::getReadProfile),
            headerPropertiesReadLevel());

        // If `null`, all properties will be fetched
        // This defer from RFC-8621 behavior (not implemented here)
        // If omitted, this defaults to: [ "partId", "blobId", "size", "name", "type", "charset", "disposition", "cid",
        // "language", "location" ]
        return readLevels.reduce(ReadProfile::combine)
            .orElse(ReadProfile.Full);
    }

    public Stream<String> asFieldList() {
        return Stream.concat(
            messageProperties.stream()
                .flatMap(Collection::stream)
                .map(MessageProperty::asFieldName),
            headersProperties.stream()
                .flatMap(Collection::stream)
                .map(HeaderProperty::asFieldName));
    }

    private Stream<ReadProfile> headerPropertiesReadLevel() {
        return headersProperties.map(collection ->
            collection.stream()
                .map(any -> ReadProfile.Header))
            .orElse(Stream.of());
    }

    private ImmutableSet<MessageProperty> buildOutputMessageProperties() {
        return this.messageProperties.orElseGet(MessageProperty::allOutputProperties);
    }

    private MessageProperties usingProperties(Sets.SetView<MessageProperty> properties) {
        return new MessageProperties(
            Optional.of(properties.immutableCopy()),
            headersProperties);
    }

    private MessageProperties ensureContains(ImmutableSet<MessageProperty> mandatoryFields) {
        return usingProperties(Sets.union(buildOutputMessageProperties(), mandatoryFields));
    }

    private MessageProperties selectBody() {
        ImmutableSet<MessageProperty> messageProperties = buildOutputMessageProperties();
        if (messageProperties.contains(MessageProperty.body)) {
            return usingProperties(
                Sets.difference(
                    Sets.union(messageProperties, ImmutableSet.of(MessageProperty.textBody)),
                    ImmutableSet.of(MessageProperty.body)));
        }
        return this;
    }

    private MessageProperties ensureHeadersMessageProperty() {
        if (headersProperties.isPresent() && !headersProperties.get().isEmpty()) {
            return usingProperties(Sets.union(
                buildOutputMessageProperties(),
                ImmutableSet.of(MessageProperty.headers)));
        }
        return this;
    }

    private MessageProperties overrideHeadersFilteringOnHeadersMessageProperty() {
        if (buildOutputMessageProperties().contains(MessageProperty.headers)) {
            return new MessageProperties(messageProperties, Optional.empty());
        }
        return this;
    }

    private enum PropertyType {
        INPUTONLY,
        INPUTOUTPUT
    }

    public enum MessageProperty implements Property {
        id("id", ReadProfile.Metadata),
        blobId("blobId", ReadProfile.Metadata),
        threadId("threadId", ReadProfile.Metadata),
        mailboxIds("mailboxIds", ReadProfile.Metadata),
        inReplyToMessageId("inReplyToMessageId", ReadProfile.Header),
        isUnread("isUnread", ReadProfile.Metadata),
        isFlagged("isFlagged", ReadProfile.Metadata),
        isAnswered("isAnswered", ReadProfile.Metadata),
        isDraft("isDraft", ReadProfile.Metadata),
        isForwarded("isForwarded", ReadProfile.Metadata),
        hasAttachment("hasAttachment", ReadProfile.Fast),
        headers("headers", ReadProfile.Header),
        from("from", ReadProfile.Header),
        to("to", ReadProfile.Header),
        cc("cc", ReadProfile.Header),
        bcc("bcc", ReadProfile.Header),
        replyTo("replyTo", ReadProfile.Header),
        subject("subject", ReadProfile.Header),
        date("date", ReadProfile.Header),
        size("size", ReadProfile.Metadata),
        preview("preview", ReadProfile.Fast),
        textBody("textBody", ReadProfile.Full),
        htmlBody("htmlBody", ReadProfile.Full),
        attachments("attachments", ReadProfile.Full),
        attachedMessages("attachedMessages", ReadProfile.Full),
        keywords("keywords", ReadProfile.Metadata),
        body("body", PropertyType.INPUTONLY, ReadProfile.Full);

        private final String property;
        private final PropertyType type;
        private final ReadProfile readProfile;

        MessageProperty(String property, ReadProfile readProfile) {
            this(property, PropertyType.INPUTOUTPUT, readProfile);
        }

        MessageProperty(String property, PropertyType type, ReadProfile readProfile) {
            this.property = property;
            this.type = type;
            this.readProfile = readProfile;
        }

        @Override
        public String asFieldName() {
            return property;
        }

        public ReadProfile getReadProfile() {
            return readProfile;
        }

        private static final ImmutableMap<String, MessageProperty> LOOKUP_MAP = Arrays.stream(values())
            .collect(ImmutableMap.toImmutableMap(v -> v.property, Function.identity()));

        public static Stream<MessageProperty> find(String property) {
            Preconditions.checkNotNull(property);
            return Optional.ofNullable(LOOKUP_MAP.get(property)).stream();
        }

        public static ImmutableSet<MessageProperty> allOutputProperties() {
            return Arrays.stream(values()).filter(MessageProperty::outputProperty).collect(ImmutableSet.toImmutableSet());
        }

        private static boolean outputProperty(MessageProperty p) {
            switch (p.type) {
                case INPUTONLY:
                    return false;
                case INPUTOUTPUT:
                    return true;
                default:
                    throw new IllegalStateException();
            }
        }
    }

    public enum ReadProfile {
        Metadata(0),
        Header(1),
        Fast(2),
        Full(3);

        public static ReadProfile combine(ReadProfile readProfile1, ReadProfile readProfile2) {
            if (readProfile1.priority > readProfile2.priority) {
                return readProfile1;
            }
            return readProfile2;
        }

        private final int priority;

        ReadProfile(int priority) {
            this.priority = priority;
        }
    }

    public static class HeaderProperty implements Property {

        public static final String HEADER_PROPERTY_PREFIX = "headers.";

        public static HeaderProperty fromFieldName(String field) {
            Preconditions.checkArgument(!isMessageHeaderProperty(field));
            return new HeaderProperty(field.toLowerCase(Locale.US));
        }

        public static HeaderProperty valueOf(String property) {
            Preconditions.checkArgument(isMessageHeaderProperty(property));
            return new HeaderProperty(stripPrefix(property).toLowerCase(Locale.US));
        }

        private static String stripPrefix(String property) {
            return property.substring(HEADER_PROPERTY_PREFIX.length());
        }

        public static boolean isMessageHeaderProperty(String property) {
            Preconditions.checkNotNull(property);
            return property.startsWith(HEADER_PROPERTY_PREFIX);
        }

        public static Stream<HeaderProperty> find(String property) {
            if (isMessageHeaderProperty(property)) {
                return Stream.of(valueOf(property));
            } else {
                return Stream.of();
            }
        }

        private String fieldName;

        private HeaderProperty(String fieldName) {
            this.fieldName = fieldName;
        }

        @Override
        public String asFieldName() {
            return fieldName;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj instanceof HeaderProperty) {
                HeaderProperty other = (HeaderProperty) obj;
                return Objects.equals(this.fieldName, other.fieldName);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return Objects.hash(fieldName);
        }

        @Override
        public String toString() {
            return Objects.toString(fieldName);
        }
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
            .add("headersProperties", headersProperties)
            .add("messageProperties", messageProperties)
            .toString();
    }
}
