/*
 * 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.qpid.protonj2.test.driver.matchers.messaging;

import static org.hamcrest.MatcherAssert.assertThat;

import java.util.Map;

import org.apache.qpid.protonj2.test.driver.codec.Codec;
import org.apache.qpid.protonj2.test.driver.codec.primitives.DescribedType;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.hamcrest.Matcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;

public abstract class AbstractMessageSectionMatcher {

    private final Logger LOG = LoggerFactory.getLogger(getClass());

    private final UnsignedLong numericDescriptor;
    private final Symbol symbolicDescriptor;

    private final Map<Object, Matcher<?>> fieldMatchers;
    private Map<Object, Object> receivedFields;

    private final boolean expectTrailingBytes;

    protected AbstractMessageSectionMatcher(UnsignedLong numericDescriptor, Symbol symbolicDescriptor, Map<Object, Matcher<?>> fieldMatchers, boolean expectTrailingBytes) {
        this.numericDescriptor = numericDescriptor;
        this.symbolicDescriptor = symbolicDescriptor;
        this.fieldMatchers = fieldMatchers;
        this.expectTrailingBytes = expectTrailingBytes;
    }

    protected Map<Object, Matcher<?>> getMatchers() {
        return fieldMatchers;
    }

    protected Map<Object, Object> getReceivedFields() {
        return receivedFields;
    }

    /**
     * @param receivedBinary
     *        The received Binary value that should be validated.
     *
     * @return the number of bytes consumed from the provided Binary
     *
     * @throws RuntimeException
     *         if the provided Binary does not match expectation in some way
     */
    public int verify(ByteBuf receivedBinary) throws RuntimeException {
        int length = receivedBinary.readableBytes();
        Codec data = Codec.Factory.create();
        long decoded = data.decode(receivedBinary);
        if (decoded > Integer.MAX_VALUE) {
            throw new IllegalStateException("Decoded more bytes than Binary supports holding");
        }

        if (decoded < length && !expectTrailingBytes) {
            throw new IllegalArgumentException(
                "Expected to consume all bytes, but trailing bytes remain: Got " + length + ", consumed " + decoded);
        }

        DescribedType decodedDescribedType = data.getDescribedType();
        verifyReceivedDescribedType(decodedDescribedType);

        // Need to cast to int, but verified earlier that it is <
        // Integer.MAX_VALUE
        return (int) decoded;
    }

    private void verifyReceivedDescribedType(DescribedType decodedDescribedType) {
        Object descriptor = decodedDescribedType.getDescriptor();
        if (!(symbolicDescriptor.equals(descriptor) || numericDescriptor.equals(descriptor))) {
            throw new IllegalArgumentException(
                "Unexpected section type descriptor. Expected " + symbolicDescriptor +
                " or " + numericDescriptor + ", but got: " + descriptor);
        }

        verifyReceivedDescribedObject(decodedDescribedType.getDescribed());
    }

    /**
     * sub-classes should implement depending on the expected content of the
     * particular section type.
     *
     * @param describedObject
     * 		the described type instance to validate.
     */
    protected abstract void verifyReceivedDescribedObject(Object describedObject);

    /**
     * Utility method for use by sub-classes that expect field-based sections,
     * i.e lists or maps.
     *
     * @param valueMap
     * 		the key / value map of fields that comprise the received section.
     */
    protected void verifyReceivedFields(Map<Object, Object> valueMap) {
        receivedFields = valueMap;

        LOG.debug("About to check the fields of the section." + "\n  Received:" + valueMap + "\n  Expectations: " + fieldMatchers);
        for (Map.Entry<Object, Matcher<?>> entry : fieldMatchers.entrySet()) {
            @SuppressWarnings("unchecked")
            Matcher<Object> matcher = (Matcher<Object>) entry.getValue();
            Object field = entry.getKey();
            assertThat("Field " + field + " value should match", valueMap.get(field), matcher);
        }
    }

    /**
     * Intended to be overridden in most cases that use the above method (but
     * not necessarily all - hence not marked as abstract)
     *
     * @param fieldIndex
     *     the field index in the list of section fields whose {@link Enum} constant is being looked up.
     *
     * @return the field enumeration value mapped to the provided index.
     */
    protected Enum<?> getField(int fieldIndex) {
        throw new UnsupportedOperationException("getFieldName is expected to be overridden by subclass if it is required");
    }
}