/*
 * 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.commons.math4.neuralnet.oned;

import java.io.Serializable;
import java.io.ObjectInputStream;

import org.apache.commons.math4.neuralnet.internal.NeuralNetException;
import org.apache.commons.math4.neuralnet.FeatureInitializer;
import org.apache.commons.math4.neuralnet.Network;

/**
 * Neural network with the topology of a one-dimensional line.
 * Each neuron defines one point on the line.
 *
 * @since 3.3
 */
public class NeuronString implements Serializable {
    /** Serial version ID. */
    private static final long serialVersionUID = 1L;
    /** Minimal number of neurons. */
    private static final int MIN_NEURONS = 2;
    /** Underlying network. */
    private final Network network;
    /** Number of neurons. */
    private final int size;
    /** Wrap. */
    private final boolean wrap;

    /**
     * Mapping of the 1D coordinate to the neuron identifiers
     * (attributed by the {@link #network} instance).
     */
    private final long[] identifiers;

    /**
     * Constructor with restricted access, solely used for deserialization.
     *
     * @param wrap Whether to wrap the dimension (i.e the first and last
     * neurons will be linked together).
     * @param featuresList Arrays that will initialize the features sets of
     * the network's neurons.
     * @throws IllegalArgumentException if {@code num < 2}.
     */
    NeuronString(boolean wrap,
                 double[][] featuresList) {
        size = featuresList.length;

        if (size < MIN_NEURONS) {
            throw new NeuralNetException(NeuralNetException.TOO_SMALL, size, MIN_NEURONS);
        }

        this.wrap = wrap;

        final int fLen = featuresList[0].length;
        network = new Network(0, fLen);
        identifiers = new long[size];

        // Add neurons.
        for (int i = 0; i < size; i++) {
            identifiers[i] = network.createNeuron(featuresList[i]);
        }

        // Add links.
        createLinks();
    }

    /**
     * Creates a one-dimensional network:
     * Each neuron not located on the border of the mesh has two
     * neurons linked to it.
     * <br>
     * The links are bi-directional.
     * Neurons created successively are neighbours (i.e. there are
     * links between them).
     * <br>
     * The topology of the network can also be a circle (if the
     * dimension is wrapped).
     *
     * @param num Number of neurons.
     * @param wrap Whether to wrap the dimension (i.e the first and last
     * neurons will be linked together).
     * @param featureInit Arrays that will initialize the features sets of
     * the network's neurons.
     * @throws IllegalArgumentException if {@code num < 2}.
     */
    public NeuronString(int num,
                        boolean wrap,
                        FeatureInitializer[] featureInit) {
        if (num < MIN_NEURONS) {
            throw new NeuralNetException(NeuralNetException.TOO_SMALL, num, MIN_NEURONS);
        }

        size = num;
        this.wrap = wrap;
        identifiers = new long[num];

        final int fLen = featureInit.length;
        network = new Network(0, fLen);

        // Add neurons.
        for (int i = 0; i < num; i++) {
            final double[] features = new double[fLen];
            for (int fIndex = 0; fIndex < fLen; fIndex++) {
                features[fIndex] = featureInit[fIndex].value();
            }
            identifiers[i] = network.createNeuron(features);
        }

        // Add links.
        createLinks();
    }

    /**
     * Retrieves the underlying network.
     * A reference is returned (enabling, for example, the network to be
     * trained).
     * This also implies that calling methods that modify the {@link Network}
     * topology may cause this class to become inconsistent.
     *
     * @return the network.
     */
    public Network getNetwork() {
        return network;
    }

    /**
     * Gets the number of neurons.
     *
     * @return the number of neurons.
     */
    public int getSize() {
        return size;
    }

    /**
     * Retrieves the features set from the neuron at location
     * {@code i} in the map.
     *
     * @param i Neuron index.
     * @return the features of the neuron at index {@code i}.
     * @throws IllegalArgumentException if {@code i} is out of range.
     */
    public double[] getFeatures(int i) {
        if (i < 0 ||
            i >= size) {
            throw new NeuralNetException(NeuralNetException.OUT_OF_RANGE, i, 0, size - 1);
        }

        return network.getNeuron(identifiers[i]).getFeatures();
    }

    /**
     * Creates the neighbour relationships between neurons.
     */
    private void createLinks() {
        for (int i = 0; i < size - 1; i++) {
            network.addLink(network.getNeuron(i), network.getNeuron(i + 1));
        }
        for (int i = size - 1; i > 0; i--) {
            network.addLink(network.getNeuron(i), network.getNeuron(i - 1));
        }
        if (wrap) {
            network.addLink(network.getNeuron(0), network.getNeuron(size - 1));
            network.addLink(network.getNeuron(size - 1), network.getNeuron(0));
        }
    }

    /**
     * Prevents proxy bypass.
     *
     * @param in Input stream.
     */
    private void readObject(ObjectInputStream in) {
        throw new IllegalStateException();
    }

    /**
     * Custom serialization.
     *
     * @return the proxy instance that will be actually serialized.
     */
    private Object writeReplace() {
        final double[][] featuresList = new double[size][];
        for (int i = 0; i < size; i++) {
            featuresList[i] = getFeatures(i);
        }

        return new SerializationProxy(wrap,
                                      featuresList);
    }

    /**
     * Serialization.
     */
    private static class SerializationProxy implements Serializable {
        /** Serializable. */
        private static final long serialVersionUID = 20130226L;
        /** Wrap. */
        private final boolean wrap;
        /** Neurons' features. */
        private final double[][] featuresList;

        /**
         * @param wrap Whether the dimension is wrapped.
         * @param featuresList List of neurons features.
         * {@code neuronList}.
         */
        SerializationProxy(boolean wrap,
                           double[][] featuresList) {
            this.wrap = wrap;
            this.featuresList = featuresList;
        }

        /**
         * Custom serialization.
         *
         * @return the {@link NeuronString} for which this instance is the proxy.
         */
        private Object readResolve() {
            return new NeuronString(wrap,
                                    featuresList);
        }
    }
}
