/*
 * 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.logging.log4j.plugins.convert;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;

import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.*;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.Provider;
import java.security.Security;
import java.util.Base64;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * Collection of basic TypeConverter implementations. May be used to register additional TypeConverters or find
 * registered TypeConverters.
 *
 * @since 2.1 Moved to the {@code convert} package.
 */
public final class TypeConverters {

    /**
     * The {@link Plugin#category() Plugin Category} to use for {@link TypeConverter} plugins.
     *
     * @since 2.1
     */
    public static final String CATEGORY = "TypeConverter";

    private static final Base64.Decoder decoder = Base64.getDecoder();

    /**
     * Parses a {@link String} into a {@link BigDecimal}.
     */
    @Plugin(name = "BigDecimal", category = CATEGORY)
    public static class BigDecimalConverter implements TypeConverter<BigDecimal> {
        @Override
        public BigDecimal convert(final String s) {
            return new BigDecimal(s);
        }
    }

    /**
     * Parses a {@link String} into a {@link BigInteger}.
     */
    @Plugin(name = "BigInteger", category = CATEGORY)
    public static class BigIntegerConverter implements TypeConverter<BigInteger> {
        @Override
        public BigInteger convert(final String s) {
            return new BigInteger(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Boolean}.
     */
    @Plugin(name = "Boolean", category = CATEGORY)
    public static class BooleanConverter implements TypeConverter<Boolean> {
        @Override
        public Boolean convert(final String s) {
            return Boolean.valueOf(s);
        }
    }

    /**
     * Converts a {@link String} into a {@code byte[]}.
     * 
     * The supported formats are:
     * <ul>
     * <li>0x0123456789ABCDEF</li>
     * <li>Base64:ABase64String</li>
     * <li>String using {@link Charset#defaultCharset()} [TODO Should this be UTF-8 instead?]</li>
     * </ul>
     */
    @Plugin(name = "ByteArray", category = CATEGORY)
    public static class ByteArrayConverter implements TypeConverter<byte[]> {

        private static final String PREFIX_0x = "0x";
        private static final String PREFIX_BASE64 = "Base64:";

        @Override
        public byte[] convert(final String value) {
            byte[] bytes;
            if (value == null || value.isEmpty()) {
                bytes = new byte[0];
            } else if (value.startsWith(PREFIX_BASE64)) {
                final String lexicalXSDBase64Binary = value.substring(PREFIX_BASE64.length());
                bytes = decoder.decode(lexicalXSDBase64Binary);
            } else if (value.startsWith(PREFIX_0x)) {
                final String lexicalXSDHexBinary = value.substring(PREFIX_0x.length());
                bytes = HexConverter.parseHexBinary(lexicalXSDHexBinary);
            } else {
                bytes = value.getBytes(Charset.defaultCharset());
            }
            return bytes;
        }
    }

    /**
     * Converts a {@link String} into a {@link Byte}.
     */
    @Plugin(name = "Byte", category = CATEGORY)
    public static class ByteConverter implements TypeConverter<Byte> {
        @Override
        public Byte convert(final String s) {
            return Byte.valueOf(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Character}.
     */
    @Plugin(name = "Character", category = CATEGORY)
    public static class CharacterConverter implements TypeConverter<Character> {
        @Override
        public Character convert(final String s) {
            if (s.length() != 1) {
                throw new IllegalArgumentException("Character string must be of length 1: " + s);
            }
            return Character.valueOf(s.toCharArray()[0]);
        }
    }

    /**
     * Converts a {@link String} into a {@code char[]}.
     */
    @Plugin(name = "CharacterArray", category = CATEGORY)
    public static class CharArrayConverter implements TypeConverter<char[]> {
        @Override
        public char[] convert(final String s) {
            return s.toCharArray();
        }
    }

    /**
     * Converts a {@link String} into a {@link Charset}.
     */
    @Plugin(name = "Charset", category = CATEGORY)
    public static class CharsetConverter implements TypeConverter<Charset> {
        @Override
        public Charset convert(final String s) {
            return Charset.forName(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Class}.
     */
    @Plugin(name = "Class", category = CATEGORY)
    public static class ClassConverter implements TypeConverter<Class<?>> {
        @Override
        public Class<?> convert(final String s) throws ClassNotFoundException {
            switch (s.toLowerCase()) {
                case "boolean":
                    return boolean.class;
                case "byte":
                    return byte.class;
                case "char":
                    return char.class;
                case "double":
                    return double.class;
                case "float":
                    return float.class;
                case "int":
                    return int.class;
                case "long":
                    return long.class;
                case "short":
                    return short.class;
                case "void":
                    return void.class;
                default:
                    return LoaderUtil.loadClass(s);
            }

        }
    }

    /**
     * Converts a {@link String} into a {@link Double}.
     */
    @Plugin(name = "Double", category = CATEGORY)
    public static class DoubleConverter implements TypeConverter<Double> {
        @Override
        public Double convert(final String s) {
            return Double.valueOf(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link File}.
     */
    @Plugin(name = "File", category = CATEGORY)
    public static class FileConverter implements TypeConverter<File> {
        @Override
        public File convert(final String s) {
            return new File(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Float}.
     */
    @Plugin(name = "Float", category = CATEGORY)
    public static class FloatConverter implements TypeConverter<Float> {
        @Override
        public Float convert(final String s) {
            return Float.valueOf(s);
        }
    }

    /**
     * Converts a {@link String} into an {@link InetAddress}.
     */
    @Plugin(name = "InetAddress", category = CATEGORY)
    public static class InetAddressConverter implements TypeConverter<InetAddress> {
        @Override
        public InetAddress convert(final String s) throws Exception {
            return InetAddress.getByName(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Integer}.
     */
    @Plugin(name = "Integer", category = CATEGORY)
    public static class IntegerConverter implements TypeConverter<Integer> {
        @Override
        public Integer convert(final String s) {
            return Integer.valueOf(s);
        }
    }

    /**
     * Converts a {@link String} into a Log4j {@link Level}. Returns {@code null} for invalid level names.
     */
    @Plugin(name = "Level", category = CATEGORY)
    public static class LevelConverter implements TypeConverter<Level> {
        @Override
        public Level convert(final String s) {
            return Level.valueOf(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Long}.
     */
    @Plugin(name = "Long", category = CATEGORY)
    public static class LongConverter implements TypeConverter<Long> {
        @Override
        public Long convert(final String s) {
            return Long.valueOf(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Path}.
     * @since 2.8
     */
    @Plugin(name = "Path", category = CATEGORY)
    public static class PathConverter implements TypeConverter<Path> {
        @Override
        public Path convert(final String s) throws Exception {
            return Paths.get(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Pattern}.
     */
    @Plugin(name = "Pattern", category = CATEGORY)
    public static class PatternConverter implements TypeConverter<Pattern> {
        @Override
        public Pattern convert(final String s) {
            return Pattern.compile(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Provider}.
     */
    @Plugin(name = "SecurityProvider", category = CATEGORY)
    public static class SecurityProviderConverter implements TypeConverter<Provider> {
        @Override
        public Provider convert(final String s) {
            return Security.getProvider(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link Short}.
     */
    @Plugin(name = "Short", category = CATEGORY)
    public static class ShortConverter implements TypeConverter<Short> {
        @Override
        public Short convert(final String s) {
            return Short.valueOf(s);
        }
    }

    /**
     * Returns the given {@link String}, no conversion takes place.
     */
    @Plugin(name = "String", category = CATEGORY)
    public static class StringConverter implements TypeConverter<String> {
        @Override
        public String convert(final String s) {
            return s;
        }
    }

    /**
     * Converts a {@link String} into a {@link URI}.
     */
    @Plugin(name = "URI", category = CATEGORY)
    public static class UriConverter implements TypeConverter<URI> {
        @Override
        public URI convert(final String s) throws URISyntaxException {
            return new URI(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link URL}.
     */
    @Plugin(name = "URL", category = CATEGORY)
    public static class UrlConverter implements TypeConverter<URL> {
        @Override
        public URL convert(final String s) throws MalformedURLException {
            return new URL(s);
        }
    }

    /**
     * Converts a {@link String} into a {@link UUID}.
     * @since 2.8
     */
    @Plugin(name = "UUID", category = CATEGORY)
    public static class UuidConverter implements TypeConverter<UUID> {
        @Override
        public UUID convert(final String s) throws Exception {
            return UUID.fromString(s);
        }
    }

    /**
     * Converts a String to a given class if a TypeConverter is available for that class. Falls back to the provided
     * default value if the conversion is unsuccessful. However, if the default value is <em>also</em> invalid, then
     * {@code null} is returned (along with a nasty status log message).
     * 
     * @param s
     *        the string to convert
     * @param clazz
     *        the class to try to convert the string to
     * @param defaultValue
     *        the fallback object to use if the conversion is unsuccessful
     * @param <T> The type of the clazz parameter.
     * @return the converted object which may be {@code null} if the string is invalid for the given type
     * @throws NullPointerException
     *         if {@code clazz} is {@code null}
     * @throws IllegalArgumentException
     *         if no TypeConverter exists for the given class
     */
    public static <T> T convert(final String s, final Class<? extends T> clazz, final Object defaultValue) {
        @SuppressWarnings("unchecked")
        final TypeConverter<T> converter = (TypeConverter<T>) TypeConverterRegistry.getInstance().findCompatibleConverter(clazz);
        if (s == null) {
            // don't debug print here, resulting output is hard to understand
            // LOGGER.debug("Null string given to convert. Using default [{}].", defaultValue);
            return parseDefaultValue(converter, defaultValue);
        }
        try {
            return converter.convert(s);
        } catch (final Exception e) {
            LOGGER.warn("Error while converting string [{}] to type [{}]. Using default value [{}].", s, clazz,
                    defaultValue, e);
            return parseDefaultValue(converter, defaultValue);
        }
    }

    @SuppressWarnings("unchecked")
    private static <T> T parseDefaultValue(final TypeConverter<T> converter, final Object defaultValue) {
        if (defaultValue == null) {
            return null;
        }
        if (!(defaultValue instanceof String)) {
            return (T) defaultValue;
        }
        try {
            return converter.convert((String) defaultValue);
        } catch (final Exception e) {
            LOGGER.debug("Can't parse default value [{}] for type [{}].", defaultValue, converter.getClass(), e);
            return null;
        }
    }

    private static final Logger LOGGER = StatusLogger.getLogger();

}
