/*
 * 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.internal.converter;

import java.util.Set;
import java.util.EnumSet;
import java.util.IllformedLocaleException;
import java.nio.charset.UnsupportedCharsetException;
import java.net.URISyntaxException;
import java.net.MalformedURLException;
import java.nio.file.InvalidPathException;
import javax.measure.format.ParserException;
import org.apache.sis.math.FunctionProperty;
import org.apache.sis.util.Locales;
import org.apache.sis.util.Numbers;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.ObjectConverter;
import org.apache.sis.util.UnconvertibleObjectException;
import org.apache.sis.util.iso.SimpleInternationalString;
import org.apache.sis.internal.util.CodeLists;
import org.apache.sis.measure.Units;


/**
 * Handles conversions between {@link String} and various kinds of objects.
 * Each inner class in this {@code StringConverter} class defines both the
 * forward and the inverse converters.
 *
 * <p>Most converters are pretty close to bijective functions, but not exactly.
 * For example conversions from {@code String} to {@link java.io.File} is not
 * completely bijective because various path separators ({@code '/'} and {@code '\'})
 * produce the same {@code File} object.</p>
 *
 * <div class="section">Special cases</div>
 * Conversion table from {@link String} to {@link java.lang.Boolean}:
 *
 * <table class="sis">
 *   <caption>Conversion table from strings</caption>
 *   <tr><th>source</th>          <th>target</th></tr>
 *   <tr><td>{@code "true"}  </td><td>{@link java.lang.Boolean#TRUE}  </td></tr>
 *   <tr><td>{@code "false"} </td><td>{@link java.lang.Boolean#FALSE} </td></tr>
 *   <tr><td>{@code "yes"}   </td><td>{@link java.lang.Boolean#TRUE}  </td></tr>
 *   <tr><td>{@code "no"}    </td><td>{@link java.lang.Boolean#FALSE} </td></tr>
 *   <tr><td>{@code "on"}    </td><td>{@link java.lang.Boolean#TRUE}  </td></tr>
 *   <tr><td>{@code "off"}   </td><td>{@link java.lang.Boolean#FALSE} </td></tr>
 *   <tr><td>{@code "1"}     </td><td>{@link java.lang.Boolean#TRUE}  </td></tr>
 *   <tr><td>{@code "0"}     </td><td>{@link java.lang.Boolean#FALSE} </td></tr>
 * </table>
 *
 * <div class="section">Immutability and thread safety</div>
 * This base class and all inner classes are immutable, and thus inherently thread-safe.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.5
 * @since   0.3
 * @module
 */
abstract class StringConverter<T> extends SystemConverter<String, T> {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -7181934724345598473L;

    /**
     * The inverse converter from the target to the source class.
     */
    private final ObjectConverter<T, String> inverse;

    /**
     * Creates a new converter for the given target class.
     *
     * @param  targetClass  the {@linkplain #getTargetClass() target class}.
     */
    @SuppressWarnings("OverridableMethodCallDuringObjectConstruction")
    StringConverter(final Class<T> targetClass) {
        super(String.class, targetClass);
        inverse = createInverse();
    }

    /**
     * Invoked by the constructor for creating the inverse converter.
     * To be overridden by classes which need a specialized instance.
     */
    ObjectConverter<T, String> createInverse() {
        return new ObjectToString<>(targetClass, this);
    }

    /**
     * While this is not a general rule for surjective functions,
     * all converters defined in this class are invertibles.
     */
    @Override
    public Set<FunctionProperty> properties() {
        return EnumSet.of(FunctionProperty.SURJECTIVE, FunctionProperty.INVERTIBLE);
    }

    /**
     * Returns the inverse converter.
     */
    @Override
    public final ObjectConverter<T, String> inverse() {
        return inverse;
    }

    /**
     * Converts the given string to the target type of this converter.
     * This method verifies that the given string is non-null and non-empty,
     * then delegates to {@link #doConvert(String)}.
     *
     * @param  source  the string to convert, or {@code null}.
     * @return the converted value, or {@code null} if the given string was null or empty.
     * @throws UnconvertibleObjectException if an error occurred during the conversion.
     */
    @Override
    public final T apply(String source) throws UnconvertibleObjectException {
        source = CharSequences.trimWhitespaces(source);
        if (source == null || source.isEmpty()) {
            return null;
        }
        try {
            return doConvert(source);
        } catch (UnconvertibleObjectException e) {
            throw e;
        } catch (Exception e) {
            throw new UnconvertibleObjectException(formatErrorMessage(source), e);
        }
    }

    /**
     * Invoked by {@link #apply(String)} for converting the given string to the target
     * type of this converter.
     *
     * @param  source  the string to convert, guaranteed to be non-null and non-empty.
     * @return the converted value.
     * @throws Exception if an error occurred during the conversion.
     */
    abstract T doConvert(String source) throws Exception;

    /**
     * Converter from {@link String} to various kinds of {@link java.lang.Number}.
     */
    public static final class Number extends StringConverter<java.lang.Number> {
        private static final long serialVersionUID = 8356246549731207392L;
        public Number() {super(java.lang.Number.class);}                            // Instantiated by ServiceLoader.

        @Override java.lang.Number doConvert(String source) throws NumberFormatException {
            return Numbers.narrowestNumber(source);
        }
    }

    public static final class Double extends StringConverter<java.lang.Double> {
        private static final long serialVersionUID = -8576620873911755486L;
        public Double() {super(java.lang.Double.class);}                            // Instantiated by ServiceLoader.

        @Override java.lang.Double doConvert(String source) throws NumberFormatException {
            return java.lang.Double.parseDouble(source);
        }
    }

    public static final class Float extends StringConverter<java.lang.Float> {
        private static final long serialVersionUID = 2301101264860653956L;
        public Float() {super(java.lang.Float.class);}                              // Instantiated by ServiceLoader.

        @Override java.lang.Float doConvert(String source) throws NumberFormatException {
            return java.lang.Float.parseFloat(source);
        }
    }

    public static final class Long extends StringConverter<java.lang.Long> {
        private static final long serialVersionUID = 4711495660311641145L;
        public Long() {super(java.lang.Long.class);}                                // Instantiated by ServiceLoader.

        @Override java.lang.Long doConvert(String source) throws NumberFormatException {
            return java.lang.Long.parseLong(source);
        }
    }

    public static final class Integer extends StringConverter<java.lang.Integer> {
        private static final long serialVersionUID = -5024227987148221073L;
        public Integer() {super(java.lang.Integer.class);}                          // Instantiated by ServiceLoader.

        @Override java.lang.Integer doConvert(String source) throws NumberFormatException {
            return java.lang.Integer.parseInt(source);
        }
    }

    public static final class Short extends StringConverter<java.lang.Short> {
        private static final long serialVersionUID = 4067703596268901375L;
        public Short() {super(java.lang.Short.class);}                              // Instantiated by ServiceLoader.

        @Override java.lang.Short doConvert(String source) throws NumberFormatException {
            return java.lang.Short.parseShort(source);
        }
    }

    public static final class Byte extends StringConverter<java.lang.Byte> {
        private static final long serialVersionUID = 6934470534898203474L;
        public Byte() {super(java.lang.Byte.class);}                                // Instantiated by ServiceLoader.

        @Override java.lang.Byte doConvert(String source) throws NumberFormatException {
            return java.lang.Byte.parseByte(source);
        }
    }

    public static final class BigDecimal extends StringConverter<java.math.BigDecimal> {
        private static final long serialVersionUID = -5949128086478498785L;
        public BigDecimal() {super(java.math.BigDecimal.class);}                    // Instantiated by ServiceLoader.

        @Override java.math.BigDecimal doConvert(String source) throws NumberFormatException {
            return new java.math.BigDecimal(source);
        }
    }

    public static final class BigInteger extends StringConverter<java.math.BigInteger> {
        private static final long serialVersionUID = 6387019773702794255L;
        public BigInteger() {super(java.math.BigInteger.class);}                    // Instantiated by ServiceLoader.

        @Override java.math.BigInteger doConvert(String source) throws NumberFormatException {
            return new java.math.BigInteger(source);
        }
    }

    public static final class Boolean extends StringConverter<java.lang.Boolean> {
        private static final long serialVersionUID = 4689076223535035309L;
        public Boolean() {super(java.lang.Boolean.class);}                          // Instantiated by ServiceLoader.

        /** See {@link StringConverter} for the conversion table. */
        @Override java.lang.Boolean doConvert(final String source) throws UnconvertibleObjectException {
            switch (source.toLowerCase(java.util.Locale.ROOT)) {
                case "true":  case "yes": case "on":  case "1": return java.lang.Boolean.TRUE;
                case "false": case "no":  case "off": case "0": return java.lang.Boolean.FALSE;
            }
            throw new UnconvertibleObjectException(formatErrorMessage(source));
        }
    }

    public static final class Locale extends StringConverter<java.util.Locale> {
        private static final long serialVersionUID = -794933131690043494L;
        public Locale() {super(java.util.Locale.class);}                            // Instantiated by ServiceLoader.

        @Override java.util.Locale doConvert(String source) throws IllformedLocaleException {
            return Locales.parse(source);
        }
    }

    public static final class Charset extends StringConverter<java.nio.charset.Charset> {
        private static final long serialVersionUID = 4375157214436581095L;
        public Charset() {super(java.nio.charset.Charset.class);}                   // Instantiated by ServiceLoader.

        @Override java.nio.charset.Charset doConvert(String source) throws UnsupportedCharsetException {
            return java.nio.charset.Charset.forName(source);
        }
    }

    public static final class File extends StringConverter<java.io.File> {
        private static final long serialVersionUID = -2157537605361631529L;
        public File() {super(java.io.File.class);}                                  // Instantiated by ServiceLoader.

        @Override java.io.File doConvert(String source) {
            return new java.io.File(source);
        }
    }

    public static final class Path extends StringConverter<java.nio.file.Path> {
        private static final long serialVersionUID = -1737315635965906042L;
        public Path() {super(java.nio.file.Path.class);}                            // Instantiated by ServiceLoader.

        @Override java.nio.file.Path doConvert(String source) throws InvalidPathException {
            return java.nio.file.Paths.get(source);
        }
    }

    public static final class URI extends StringConverter<java.net.URI> {
        private static final long serialVersionUID = 7266486748714603336L;
        public URI() {super(java.net.URI.class);}                                   // Instantiated by ServiceLoader.

        @Override java.net.URI doConvert(String source) throws URISyntaxException {
            return new java.net.URI(source);
        }
    }

    public static final class URL extends StringConverter<java.net.URL> {
        private static final long serialVersionUID = -6518011235037500143L;
        public URL() {super(java.net.URL.class);}                                   // Instantiated by ServiceLoader.

        @Override java.net.URL doConvert(String source) throws MalformedURLException {
            return new java.net.URL(source);
        }
    }

    public static final class Unit extends StringConverter<javax.measure.Unit<?>> {
        private static final long serialVersionUID = -1809497218136016210L;
        @SuppressWarnings("unchecked")
        public Unit() {super((Class) javax.measure.Unit.class);}               // Instantiated by ServiceLoader.

        @Override javax.measure.Unit<?> doConvert(String source) throws ParserException {
            return Units.valueOf(source);
        }
    }

    public static final class Angle extends StringConverter<org.apache.sis.measure.Angle> {
        private static final long serialVersionUID = -6937967772504961327L;
        public Angle() {super(org.apache.sis.measure.Angle.class);}                 // Instantiated by ServiceLoader.

        @Override org.apache.sis.measure.Angle doConvert(String source) throws NumberFormatException {
            return new org.apache.sis.measure.Angle(source);
        }
    }

    public static final class InternationalString extends StringConverter<org.opengis.util.InternationalString> {
        private static final long serialVersionUID = -7386778914761469877L;
        public InternationalString() {super(org.opengis.util.InternationalString.class);} // Instantiated by ServiceLoader.

        @Override org.opengis.util.InternationalString doConvert(String source) {
            return new SimpleInternationalString(source);
        }

        /** Declares that the converter is bijective. */
        @Override public Set<FunctionProperty> properties() {
            return bijective();
        }
    }

    /**
     * Converter from {@link String} to {@link org.opengis.util.CodeList}.
     * This converter is particular in that it requires the target class in argument
     * to the constructor.
     *
     * <p>Instances of this class are created by
     * {@link SystemRegistry#createConverter(Class, Class)}.</p>
     */
    static final class CodeList<T extends org.opengis.util.CodeList<T>> extends StringConverter<T> {
        /** For cross-version compatibility on serialization. */
        private static final long serialVersionUID = -6351669842222010105L;

        /** Creates a new converter for the given code list. */
        CodeList(final Class<T> targetClass) {
            super(targetClass);
        }

        /** Converts the given string to the target type of this converter. */
        @Override T doConvert(final String source) {
            final T code = CodeLists.forName(targetClass, source, false);
            if (code == null) {
                throw new UnconvertibleObjectException(formatErrorMessage(source));
            }
            return code;
        }

        /** Invoked by the constructor for creating the inverse converter. */
        @Override ObjectConverter<T, String> createInverse() {
            return new ObjectToString.CodeList<>(targetClass, this);
        }
    }

    /**
     * Converter from {@link String} to {@link java.lang.Enum}.
     * This converter is particular in that it requires the target class in argument
     * to the constructor.
     *
     * <p>Instances of this class are created by
     * {@link SystemRegistry#createConverter(Class, Class)}.</p>
     */
    static final class Enum<T extends java.lang.Enum<T>> extends StringConverter<T> {
        /** For cross-version compatibility on serialization. */
        private static final long serialVersionUID = -4124617013044304640L;

        /** Creates a new converter for the given enumeration. */
        Enum(final Class<T> targetClass) {
            super(targetClass);
        }

        /** Converts the given string to the target type of this converter. */
        @Override T doConvert(final String source) {
            final T code = CodeLists.forName(targetClass, source);
            if (code == null) {
                throw new UnconvertibleObjectException(formatErrorMessage(source));
            }
            return code;
        }

        /** Invoked by the constructor for creating the inverse converter. */
        @Override ObjectConverter<T, String> createInverse() {
            return new ObjectToString.Enum<>(targetClass, this);
        }
    }
}
