/*
 * 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.felix.utils.resource;

import java.util.Map;

import org.osgi.framework.Version;
import org.osgi.resource.Resource;

public final class ResourceUtils {

    private ResourceUtils() {
        throw new UnsupportedOperationException();
    }

    public static String toString(Resource res, String namespace, Map<String, Object> attrs, Map<String, String> dirs) {
        StringBuilder sb = new StringBuilder();
        if (res != null) {
            sb.append("[").append(res).append("] ");
        }
        sb.append(namespace);
        for (String key : attrs.keySet()) {
            sb.append("; ");
            append(sb, key, attrs.get(key), true);
        }
        for (String key : dirs.keySet()) {
            sb.append("; ");
            append(sb, key, dirs.get(key), false);
        }
        return sb.toString();
    }

    private static void append(StringBuilder sb, String key, Object val, boolean attribute) {
        sb.append(key);
        if (val instanceof Version) {
            sb.append(":Version=");
            sb.append(val);
        } else if (val instanceof Long) {
            sb.append(":Long=");
            sb.append(val);
        } else if (val instanceof Double) {
            sb.append(":Double=");
            sb.append(val);
        } else if (val instanceof Iterable) {
            Iterable<?> it = (Iterable<?>) val;
            String scalar = null;
            for (Object o : it) {
                String ts;
                if (o instanceof String) {
                    ts = "String";
                } else if (o instanceof Long) {
                    ts = "Long";
                } else if (o instanceof Double) {
                    ts = "Double";
                } else if (o instanceof Version) {
                    ts = "Version";
                } else {
                    throw new IllegalArgumentException("Unsupported scalar type: " + o);
                }
                if (scalar == null) {
                    scalar = ts;
                } else if (!scalar.equals(ts)) {
                    throw new IllegalArgumentException("Unconsistent list type for attribute " + key);
                }
            }
            sb.append(":List<").append(scalar).append(">=");
            sb.append("\"");
            boolean first = true;
            for (Object o : it) {
                if (first) {
                    first = false;
                } else {
                    sb.append(",");
                }
                sb.append(o.toString().replace("\"", "\\\"").replace(",", "\\,"));
            }
            sb.append("\"");
        } else {
            sb.append(attribute ? "=" : ":=");
            String s = val.toString();
            if (s.matches("[0-9a-zA-Z_\\-.]*")) {
                sb.append(s);
            } else {
                sb.append("\"").append(s.replace("\"", "\\\\")).append("\"");
            }
        }
    }
}
