/*
 * 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 com.baidu.hugegraph.config;

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

import org.apache.commons.configuration.PropertyConverter;
import org.slf4j.Logger;

import com.baidu.hugegraph.util.E;
import com.baidu.hugegraph.util.Log;
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 {
                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);
    }
}
