/*
 * 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.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

import org.apache.hugegraph.util.E;
import com.google.common.base.Predicate;

public class ConfigListOption<T> extends ConfigOption<List<T>> {

    private final Class<T> elemClass;

    @SuppressWarnings("unchecked")
    public ConfigListOption(String name, String desc,
                            Predicate<List<T>> pred, T... values) {
        this(name, false, desc, pred, null, Arrays.asList(values));
    }

    @SuppressWarnings("unchecked")
    public ConfigListOption(String name, boolean required, String desc,
                            Predicate<List<T>> pred, Class<T> clazz,
                            List<T> values) {
        super(name, required, desc, pred,
              (Class<List<T>>) values.getClass(), values);
        if (clazz == null && values.size() > 0) {
            clazz = (Class<T>) values.get(0).getClass();
        }
        E.checkArgumentNotNull(clazz, "Element class can't be null");
        this.elemClass = clazz;
    }

    @Override
    protected boolean forList() {
        return true;
    }

    @Override
    protected List<T> parse(String value) {
        return convert(value, part -> this.parse(part, this.elemClass));
    }

    @SuppressWarnings("unchecked")
    public static <T> List<T> convert(Object value, Function<String, ?> conv) {
        if (value instanceof List) {
            return (List<T>) value;
        }
        // If target data type is List, parse it as a list
        String str = (String) value;
        if (str.startsWith("[") && str.endsWith("]")) {
            str = str.substring(1, str.length() - 1);
        }

        String[] parts = str.split(",");
        List<T> results = new ArrayList<>(parts.length);
        for (String part : parts) {
            results.add((T) conv.apply(part.trim()));
        }
        return results;
    }
}
