/*
 * 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.tamaya.spisupport;

import org.apache.tamaya.Configuration;
import org.apache.tamaya.ConfigurationSnapshot;
import org.apache.tamaya.TypeLiteral;
import org.apache.tamaya.spi.ConfigurationContext;
import org.apache.tamaya.spi.PropertyConverter;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * /**
 * Configuration implementation that stores all current values of a given (possibly dynamic, contextual and non server
 * capable instance) and is fully serializable. Note that hereby only the scannable key/createValue pairs are considered.
 */
public class DefaultConfigurationSnapshot implements ConfigurationSnapshot, Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * The properties frozen.
     */
    private DefaultConfiguration snapshot;
    private long frozenAt = System.nanoTime();
    private UUID id = UUID.randomUUID();
    private DefaultConfigurationContext context;
    private Set<String> keys = new HashSet<>();

    /**
     * Constructor.
     *
     * @param config The base configuration.
     * @param keys The keys to evaluate, not null.
     */
    public DefaultConfigurationSnapshot(Configuration config, Iterable<String> keys) {
        for(String k:keys) {
            this.keys.add(k);
        }
        ConfigurationContext ctx = config.getContext();
        MetadataProvider metadataProvider = ctx.getServiceContext().getService(MetadataProvider.class,
                DefaultMetaDataProvider::new);
        context = new DefaultConfigurationContext(ctx.getServiceContext(),
                ctx.getPropertyFilters(),
                ctx.getPropertySources().stream()
                        .map(ps -> DefaultPropertySourceSnapshot.of(ps, this.keys)).collect(Collectors.toList()),
                ctx.getPropertyConverters(),
                metadataProvider);
        this.snapshot = new DefaultConfiguration(context);
        if(this.keys.isEmpty()){
            this.keys.addAll(this.snapshot.getProperties().keySet());
        }
        this.keys = Collections.unmodifiableSet(this.keys);
    }

    /**
     * Constructor.
     *
     * @param config The base configuration.
     */
    public DefaultConfigurationSnapshot(Configuration config) {
        ConfigurationContext ctx = config.getContext();
        MetadataProvider metadataProvider = ctx.getServiceContext().getService(MetadataProvider.class,
                DefaultMetaDataProvider::new);
        context = new DefaultConfigurationContext(ctx.getServiceContext(),
                ctx.getPropertyFilters(),
                ctx.getPropertySources().stream()
                        .map(ps -> new DefaultPropertySourceSnapshot(ps)).collect(Collectors.toList()),
                ctx.getPropertyConverters(),
                metadataProvider);
        this.snapshot = new DefaultConfiguration(context);
        this.keys = Collections.unmodifiableSet(this.snapshot.getProperties().keySet());
    }


    @Override
    public ConfigurationSnapshot getSnapshot(Iterable<String> keys) {
        return new DefaultConfigurationSnapshot(this, keys);
    }

    /**
     * Get the evaluated keys of this frozen coinfiguration.
     * @return the keys, not null.
     */
    @Override
    public Set<String> getKeys() {
        return keys;
    }

    @Override
    public String get(String key) {
        return this.snapshot.get(key);
    }

    @Override
    public String getOrDefault(String key, String defaultValue) {
        return this.snapshot.getOrDefault(key, defaultValue);
    }

    @Override
    public <T> T getOrDefault(String key, Class<T> type, T defaultValue) {
        return this.snapshot.getOrDefault(key, type, defaultValue);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T get(String key, Class<T> type) {
        return snapshot.get(key, type);
    }

    /**
     * Accesses the current String createValue for the given key and tries to convert it
     * using the {@link PropertyConverter} instances provided by the current
     * {@link ConfigurationContext}.
     *
     * @param key  the property's absolute, or relative path, e.g. @code
     *             a/b/c/d.myProperty}.
     * @param type The target type required, not null.
     * @param <T>  the createValue type
     * @return the converted createValue, never null.
     */
    @Override
    public <T> T get(String key, TypeLiteral<T> type) {
        return snapshot.get(key, type);
    }

    @Override
    public <T> T getOrDefault(String key, TypeLiteral<T> type, T defaultValue) {
        return snapshot.getOrDefault(key, type, defaultValue);
    }

    @Override
    public Map<String, String> getProperties() {
        return snapshot.getProperties();
    }

    @Override
    public ConfigurationContext getContext() {
        return snapshot.getContext();
    }

    /**
     * <p>Returns the moment in time when this frozen configuration has been created.</p>
     *
     * <p>The time is taken from {@linkplain System#currentTimeMillis()}</p>
     *
     * @see System#currentTimeMillis()
     * @return the moment in time when this configuration has been created
     */
    @Override
    public long getTimestamp() {
        return frozenAt;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        DefaultConfigurationSnapshot that = (DefaultConfigurationSnapshot) o;

        if (frozenAt != that.frozenAt) {
            return false;
        }
        return Objects.equals(snapshot, that.snapshot);
    }

    @Override
    public int hashCode() {
        return Objects.hash(frozenAt, snapshot);
    }

    @Override
    public String toString() {
        return "FrozenConfiguration{" +
                "id=" + getId() + "," +
                "frozenAt=" + frozenAt + "," +
                "config=" + snapshot +
                '}';
    }

    /**
     * <p>Returns the unique id of this frozen configuration.</p>
     *
     * @return the unique id of this frozen configuration, never {@code null}
     */
    public UUID getId() {
        return id;
    }

}
