/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed 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.onosproject.cfg.impl;

import com.google.common.collect.ImmutableSet;
import org.onosproject.cfg.ConfigProperty;
import org.onosproject.cfg.ConfigProperty.Type;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Set;

import static org.onosproject.cfg.ConfigProperty.defineProperty;

/**
 * Utility for writing and reading configuration property definition file.
 */
public final class ConfigPropertyDefinitions {

    private static final String FMT = "%s|%s|%s|%s\n";
    private static final String SEP = "\\|";
    private static final String COMMENT = "#";

    private ConfigPropertyDefinitions() {
    }

    /**
     * Writes the specified set of property definitions into the given output
     * stream.
     *
     * @param stream output stream
     * @param props  properties whose definitions are to be written
     * @throws java.io.IOException if unable to write the stream
     */
    public static void write(OutputStream stream, Set<ConfigProperty> props) throws IOException {
        try (PrintWriter pw = new PrintWriter(new OutputStreamWriter(stream))) {
            props.forEach(p -> pw.format(FMT, p.name(), p.type(), p.description(), p.defaultValue()));
        }
    }

    /**
     * Reads the specified input stream and creates from its contents a
     * set of property definitions.
     *
     * @param stream input stream
     * @return properties whose definitions are contained in the stream
     * @throws java.io.IOException if unable to read the stream
     */
    public static Set<ConfigProperty> read(InputStream stream) throws IOException {
        ImmutableSet.Builder<ConfigProperty> builder = ImmutableSet.builder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
            String line;
            while ((line = br.readLine()) != null) {
                if (!line.isEmpty() && !line.startsWith(COMMENT)) {
                    String[] f = line.split(SEP, 4);
                    builder.add(defineProperty(f[0], Type.valueOf(f[1]), f[2], f[3]));
                }
            }
        }
        return builder.build();
    }

}
