/*
 * 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.jackrabbit.oak.run.cli;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.primitives.Ints;
import joptsimple.BuiltinHelpFormatter;
import joptsimple.HelpFormatter;
import joptsimple.OptionDescriptor;
import joptsimple.OptionSpec;
import joptsimple.internal.Strings;

import static com.google.common.base.StandardSystemProperty.LINE_SEPARATOR;

import org.jetbrains.annotations.Nullable;

public class OakHelpFormatter implements HelpFormatter {
    private static final int COL_WIDTH = 120;
    private final List<OptionsBean> optionBeans;
    private final String commandName;
    private final String connectionString;
    private final String summary;

    public OakHelpFormatter(Iterable<OptionsBean> optionBeans, @Nullable String commandName,
                            @Nullable String summary,@Nullable String connectionString) {
        this.optionBeans = Lists.newArrayList(optionBeans);
        this.commandName = commandName;
        this.summary = summary;
        this.connectionString = connectionString;
    }

    @Override
    public String format(Map<String, ? extends OptionDescriptor> options) {
        Map<String, ? extends OptionDescriptor> clonedOptions = Maps.newHashMap(options);
        List<OptionCategory> optionCategories = categorise(clonedOptions);
        //TODO Take care of left over options

        StringBuilder builder = new StringBuilder();
        builder.append(new MainSectionFormatter().format(options)).append(LINE_SEPARATOR.value());

        for (OptionCategory c : optionCategories){
            builder.append(c.format()).append(LINE_SEPARATOR.value());
        }

        return builder.toString();
    }

    private List<OptionCategory> categorise(Map<String, ? extends OptionDescriptor> options) {
        List<OptionCategory> result = new ArrayList<>();

        for (OptionsBean bean : optionBeans) {
            Map<String, OptionDescriptor> optsForThisBean = new HashMap<>();
            Map<String, OptionDescriptor> operationsForThisBean = new HashMap<>();
            for (String name : getOptionNames(bean)) {
                OptionDescriptor desc = options.remove(name);
                if (desc != null) {
                    if (bean.operationNames().contains(name)){
                        operationsForThisBean.put(name, desc);
                    } else {
                        optsForThisBean.put(name, desc);
                    }
                }
            }
            result.add(new OptionCategory(bean, optsForThisBean, operationsForThisBean));
        }
        Collections.sort(result, Collections.reverseOrder());
        return result;
    }

    private static int getColWidth() {
        return COL_WIDTH;
    }

    private static Set<String> getOptionNames(OptionsBean bean) {
        Set<String> names = new HashSet<>();
        try {
            for (Field field : bean.getClass().getDeclaredFields()) {
                if (OptionSpec.class.isAssignableFrom(field.getType())) {
                    field.setAccessible(true);
                    OptionSpec spec = (OptionSpec) field.get(bean);
                    names.addAll(spec.options());
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return names;
    }


    private static class OptionCategory implements Comparable<OptionCategory> {
        final OptionsBean bean;
        final Map<String, ? extends OptionDescriptor> options;
        final Map<String, ? extends OptionDescriptor> operations;

        public OptionCategory(OptionsBean bean, Map<String, ? extends OptionDescriptor> options,
                              Map<String, OptionDescriptor> operations) {
            this.bean = bean;
            this.options = options;
            this.operations = operations;
        }

        public String format() {
            StringBuilder builder = new StringBuilder();
            builder.append(new CategoryFormatter(bean).format(options));
            if (!operations.isEmpty()) {
                builder.append(LINE_SEPARATOR.value());
                builder.append(new OperationsFormatter().format(operations));
            }
            return builder.toString();
        }

        @Override
        public int compareTo(OptionCategory that) {
            return Ints.compare(this.bean.order(), that.bean.order());
        }
    }

    private static class CategoryFormatter extends BuiltinHelpFormatter {
        final OptionsBean bean;

        public CategoryFormatter(OptionsBean bean) {
            super(getColWidth(), 2);
            this.bean = bean;
        }

        @Override
        protected void addRows(Collection<? extends OptionDescriptor> options) {
            addHeader();
            super.addRows(options);
        }

        @Override
        protected void addNonOptionsDescription(Collection<? extends OptionDescriptor> options) {
            //Noop call as category options do not specify non options
        }

        private void addHeader() {
            String title = bean.title();
            if (title != null) {
                addNonOptionRow(title);
                addNonOptionRow(Strings.repeat('=', title.length()));
            }

            if (bean.description() != null) {
                addNonOptionRow(bean.description());
            }
        }
    }

    /**
     * Used for rending options which are "operations"
     */
    private static class OperationsFormatter extends BuiltinHelpFormatter {

        public static final String OPERATIONS = "Operations";

        public OperationsFormatter() {
            super(getColWidth(), 2);
        }

        @Override
        protected void addHeaders(Collection<? extends OptionDescriptor> options) {
            addOptionRow(OPERATIONS, message( "description.header" ) );
            addOptionRow( Strings.repeat('-', OPERATIONS.length()), message( "description.divider" ) );
        }

        @Override
        protected void addNonOptionsDescription(Collection<? extends OptionDescriptor> options) {
            //Noop call as category options do not specify non options
        }
    }

    /**
     * Formatter for the first section of the help. It dumps the connection string, command
     * and summary only. No options are handled by this formatter
     */
    private class MainSectionFormatter extends BuiltinHelpFormatter {

        public MainSectionFormatter(){
            super(getColWidth(), 2);
        }

        @Override
        protected void addRows(Collection<? extends OptionDescriptor> options) {
            String firstLine = commandName != null ? commandName + " " : "";
            if (connectionString != null) {
                firstLine += connectionString;
            }

            addNonOptionRow(firstLine);

            if (summary != null) {
                addNonOptionRow(summary);
            }

            fitRowsToWidth();
        }
    }
}
