/*
 * 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.sis.feature;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import org.opengis.feature.Feature;
import org.apache.sis.internal.util.StandardDateFormat;

import static java.util.Collections.singletonMap;


/**
 * Compares {@link org.apache.sis.feature} memory usage with a plain {@link HashMap}.
 * This class simulates creation of features having the following properties:
 *
 * <ul>
 *   <li>{@code "city"}      : {@link String}</li>
 *   <li>{@code "longitude"} : {@link Float}</li>
 *   <li>{@code "latitude"}  : {@link Float}</li>
 * </ul>
 */
public final class FeatureMemoryBenchmark {
    /**
     * Features created by the benchmark. We need to keep reference to all of them
     * for preventing the garbage collector to free memory.
     */
    private final List<Object> features;

    /**
     * If we use SIS implementation, the feature type. Otherwise {@code null}.
     */
    private final DefaultFeatureType type;

    /**
     * In the case of non-SIS implementation, whether we use simple features or complex features.
     */
    private final boolean isSimple;

    /**
     * Random number generator for feature data.
     */
    private final Random random;

    /**
     * A buffer for generating random strings.
     */
    private final char[] buffer;

    /**
     * Creates a new benchmark.
     *
     * @param useSIS    {@code true} for using SIS implementation, or {@code false} for {@link HashMap}.
     * @param isSimple  in the case of non-SIS implementation, whether we use simple features or complex features.
     */
    private FeatureMemoryBenchmark(final boolean useSIS, final boolean isSimple) {
        features = new ArrayList<>(100000);
        this.isSimple = isSimple;
        if (useSIS) {
            type = new DefaultFeatureType     (singletonMap("name", "City"), false, null,
                    new DefaultAttributeType<>(singletonMap("name", "city"),     String.class, 1, 1, null),
                    new DefaultAttributeType<>(singletonMap("name", "longitude"), Float.class, 1, 1, null),
                    new DefaultAttributeType<>(singletonMap("name", "latitude"),  Float.class, 1, 1, null));
        } else {
            type = null;
        }
        random = new Random();
        buffer = new char[8];
    }

    /**
     * The old feature implementation.
     */
    private static final class SimpleFeature {
        final HashMap<String, Object> attributes = new HashMap<>(8);
    }

    /**
     * A more complete feature implementation.
     */
    private static final class ComplexFeature {
        final HashMap<String, List<Property>> properties = new HashMap<>(8);
    }

    /**
     * The property to be stored in {@link ComplexFeature}.
     */
    private static final class Property {
        final Object value;

        private Property(final Object value) {
            this.value = value;
        }

        static List<Property> asList(final Object value) {
            final List<Property> list = new ArrayList<>(2);
            list.add(new Property(value));
            return list;
        }
    }

    /**
     * Creates a new feature instance with random data.
     */
    private Object createFeature() {
        for (int i=0; i<buffer.length; i++) {
            buffer[i] = (char) ('A' + random.nextInt(26));
        }
        final String city      = new String(buffer);
        final Float  latitude  = random.nextFloat() * 180 -  90;
        final Float  longitude = random.nextFloat() * 360 - 180;
        if (type != null) {
            final Feature feature = type.newInstance();
            feature.setPropertyValue("city",      city);
            feature.setPropertyValue("latitude",  latitude);
            feature.setPropertyValue("longitude", longitude);
            return feature;
        } else if (isSimple) {
            final SimpleFeature feature = new SimpleFeature();
            feature.attributes.put("city",      city);
            feature.attributes.put("latitude",  latitude);
            feature.attributes.put("longitude", longitude);
            return feature;
        } else {
            final ComplexFeature feature = new ComplexFeature();
            feature.properties.put("city",      Property.asList(city));
            feature.properties.put("latitude",  Property.asList(latitude));
            feature.properties.put("longitude", Property.asList(longitude));
            return feature;
        }
    }

    /**
     * Creates a bunch of features until we get out of memory.
     */
    private void run() {
        for (int i=0; i<10000000; i++) {
            final Object feature;
            try {
                feature = createFeature();
            } catch (OutOfMemoryError e) {
                final int n = features.size();
                features.clear();
                System.gc();
                System.console().printf("Feature count: %d%n", n);
                return;
            }
            features.add(feature);
        }
    }

    /**
     * Runs from the command line. This method expect one argument, which is "sis", "simple" or "complex".
     *
     * @param  arguments  command line arguments.
     */
    public static void main(final String[] arguments) {
        if (arguments.length == 1) {
            final String arg = arguments[0];
            final boolean useSIS = arg.equalsIgnoreCase("sis");
            boolean isSimple = false;
            if (useSIS || (isSimple = arg.equalsIgnoreCase("simple")) || arg.equalsIgnoreCase("complex")) {
                final FeatureMemoryBenchmark b = new FeatureMemoryBenchmark(useSIS, isSimple);
                long time = System.nanoTime();
                b.run();
                time = System.nanoTime() - time;
                System.console().printf("Ellapsed time: %f%n", time / (float) StandardDateFormat.NANOS_PER_SECOND);
                return;
            }
        }
        System.console().printf("Expected argument: 'sis', 'simple' or 'complex'.%n");
    }
}
