/*
 * Copyright 2017 HugeGraph Authors
 *
 * 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.hugegraph.config;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;

import org.apache.hugegraph.util.E;
import org.apache.hugegraph.util.Log;
import org.apache.commons.configuration.PropertyConverter;
import org.slf4j.Logger;

import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;

public class TypedOption<T, R> {

    private static final Logger LOG = Log.logger(TypedOption.class);

    private static final Set<Class<?>> ACCEPTED_DATA_TYPES;
    private static final String ACCEPTED_DATA_TYPES_STRING;

    static {
        ACCEPTED_DATA_TYPES = ImmutableSet.of(
                Boolean.class,
                Short.class,
                Integer.class,
                Byte.class,
                Long.class,
                Float.class,
                Double.class,
                String.class,
                String[].class,
                Class.class,
                List.class
        );

        ACCEPTED_DATA_TYPES_STRING = Joiner.on(", ").join(ACCEPTED_DATA_TYPES);
    }

    private final String name;
    private final String desc;
    private final boolean required;
    private final Class<T> dataType;
    private final T defaultValue;
    private final Predicate<T> checkFunc;

    @SuppressWarnings("unchecked")
    public TypedOption(String name, boolean required, String desc,
                       Predicate<T> pred, Class<T> type, T value) {
        E.checkNotNull(name, "name");
        E.checkNotNull(type, "dataType");

        this.name = name;
        this.dataType = (Class<T>) this.checkAndAssignDataType(type);
        this.defaultValue = value;
        this.required = required;
        this.desc = desc;
        this.checkFunc = pred;

        this.check(this.defaultValue);
    }

    private Class<?> checkAndAssignDataType(Class<T> dataType) {
        for (Class<?> clazz : ACCEPTED_DATA_TYPES) {
            if (clazz.isAssignableFrom(dataType)) {
                return clazz;
            }
        }

        String msg = String.format("Input data type '%s' doesn't belong " +
                                   "to acceptable type set: [%s]",
                                   dataType, ACCEPTED_DATA_TYPES_STRING);
        throw new IllegalArgumentException(msg);
    }

    public String name() {
        return this.name;
    }

    public Class<T> dataType() {
        return this.dataType;
    }

    public String desc() {
        return this.desc;
    }

    public boolean required() {
        return this.required;
    }

    public R defaultValue() {
        return this.convert(this.defaultValue);
    }

    public R parseConvert(String value) {
        T parsed = this.parse(value);
        this.check(parsed);
        return this.convert(parsed);
    }

    @SuppressWarnings("unchecked")
    protected T parse(String value) {
        return (T) this.parse(value, this.dataType);
    }

    protected Object parse(String value, Class<?> dataType) {
        if (dataType.equals(String.class)) {
            return value;
        } else if (dataType.equals(Class.class)) {
            try {
                if (value.startsWith("class")) {
                    value = value.substring("class".length()).trim();
                }
                return Class.forName(value);
            } catch (ClassNotFoundException e) {
                throw new ConfigException(
                          "Failed to parse Class from String '%s'", e, value);
            }
        } else if (List.class.isAssignableFrom(dataType)) {
            E.checkState(this.forList(),
                         "List option can't be registered with class %s",
                         this.getClass().getSimpleName());
        }

        // Use PropertyConverter method `toXXX` convert value
        String methodTo = "to" + dataType.getSimpleName();
        try {
            Method method = PropertyConverter.class.getMethod(
                            methodTo, Object.class);
            return method.invoke(null, value);
        } catch (ReflectiveOperationException e) {
            LOG.error("Invalid type of value '{}' for option '{}'",
                      value, this.name, e);
            throw new ConfigException(
                      "Invalid type of value '%s' for option '%s', " +
                      "expect '%s' type",
                      value, this.name, dataType.getSimpleName());
        }
    }

    protected void check(Object value) {
        E.checkNotNull(value, "value", this.name);
        if (!this.dataType.isInstance(value)) {
            throw new ConfigException(
                      "Invalid type of value '%s' for option '%s', " +
                      "expect type %s but got %s", value, this.name,
                      this.dataType.getSimpleName(),
                      value.getClass().getSimpleName());
        }

        if (this.checkFunc != null) {
            @SuppressWarnings("unchecked")
            T result = (T) value;
            if (!this.checkFunc.apply(result)) {
                throw new ConfigException("Invalid option value for '%s': %s",
                                          this.name, value);
            }
        }
    }

    @SuppressWarnings("unchecked")
    protected R convert(T value) {
        return (R) value;
    }

    protected boolean forList() {
        return false;
    }

    @Override
    public String toString() {
        return String.format("[%s]%s=%s", this.dataType.getSimpleName(),
                             this.name, this.defaultValue);
    }
}
