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

import org.apache.nlpcraft.common.*;
import java.util.*;

/**
 * Provides support for mutable runtime-only metadata.
 * <p>
 * Read full documentation in <a target=_ href="https://nlpcraft.apache.org/data-model.html">Data Model</a> section and review
 * <a target=_ href="https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples">examples</a>.
 */
public interface NCMetadata {
    /**
     * Factory for creating metadata out of standard map.
     *
     * @param map Map to convert to metadata.
     * @return Newly created metadata container.
     */
    static NCMetadata apply(Map<String, Object> map) {
        return () -> map;
    }

    /**
     * Gets mutable metadata underlying container.
     * Returned map can be used to mutate the metadata or perform any other operations.
     *
     * @return Mutable, underlying metadata container.
     * @see #meta(String)
     * @see #metaOpt(String)
     * @see #meta(String, Object)
     */
    Map<String, Object> getMetadata();

    /**
     * Shortcut method to get given optional metadata property. Equivalent to:
     * <pre class="brush: java">
     *      Optional.ofNullable((T)getMetadata().get(prop));
     * </pre>
     *
     * @param prop Metadata property name.
     * @param <T> Type of the metadata property.
     * @return Metadata optional property value.
     */
    @SuppressWarnings("unchecked")
    default <T> Optional<T> metaOpt(String prop) {
        return Optional.ofNullable((T)getMetadata().get(prop));
    }

    /**
     * Shortcut method to get given metadata property. Equivalent to:
     * <pre class="brush: java">
     *      (T)getMetadata().get(prop);
     * </pre>
     *
     * @param prop Metadata property name.
     * @param <T> Type of the metadata property.
     * @return Metadata property value or {@code null} if given metadata property not found.
     */
    @SuppressWarnings("unchecked")
    default <T> T meta(String prop) {
        return (T)getMetadata().get(prop);
    }

    /**
     * Shortcut method to get given mandatory metadata property. Equivalent to:
     * <pre class="brush: java">
     *     T t = (T)getMetadata().get(prop);
     *     if (t == null)
     *         throw new NCException("Mandatory metadata property not found: " + prop);
     *     else
     *         return t;
     * </pre>
     *
     * @param prop Metadata property name.
     * @param <T> Type of the metadata property.
     * @return Metadata property value or throws an exception if given metadata property not found.
     * @throws NCException Thrown if given metadata property not found.
     */
    default <T> T metax(String prop) throws NCException {
        T t = meta(prop);

        if (t == null)
            throw new NCException("Mandatory metadata property not found: " + prop);
        else
            return t;
    }

    /**
     * Shortcut method to get given metadata property. Equivalent to:
     * <pre class="brush: java">
     *      getMetadata().get(tokId, prop, dflt);
     * </pre>
     *
     * @param prop Metadata property name.
     * @param dflt Default value to return if specified one isn't set.
     * @param <T> Type of the metadata property.
     * @return Metadata property value or default value if one isn't set.
     */
    @SuppressWarnings("unchecked")
    default <T> T meta(String prop, T dflt) {
        return (T)getMetadata().getOrDefault(prop, dflt);
    }
}
