/*
 * Copyright (c) 2010-2025 Contributors to the openHAB project
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.openhab.core.model.thing.valueconverter;

import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.util.Strings;
import org.openhab.core.thing.UID;

/**
 * A {@link UIDtoStringConverter} is used to create {@link UID} string
 * representations from an input string and vice versa. If a segment of the
 * parsed {@link UID} string doesn't match the ID rule, it will be escaped.
 *
 * @author Alex Tugarev - Initial contribution
 */
public class UIDtoStringConverter implements IValueConverter<String> {

    private static final String SEPARATOR = ":";

    @Override
    public String toValue(final String string, INode node) throws ValueConverterException {
        if (string == null) {
            return null;
        }
        String[] ids = string.split(SEPARATOR);
        for (int i = 0; i < ids.length; i++) {
            String id = ids[i];
            if (id != null && id.startsWith("\"") && id.endsWith("\"")) {
                try {
                    ids[i] = Strings.convertFromJavaString(id.substring(1, id.length() - 1), true);
                } catch (IllegalArgumentException e) {
                    throw new ValueConverterException(e.getMessage(), node, e);
                }
            }
        }
        return String.join(SEPARATOR, ids);
    }

    @Override
    public String toString(String value) throws ValueConverterException {
        if (value == null) {
            throw new ValueConverterException("Value may not be null.", null, null);
        }
        String[] ids = value.split(SEPARATOR);
        for (int i = 0; i < ids.length; i++) {
            String id = ids[i];
            if (id != null && !id.matches("[A-Za-z0-9_]*")) {
                // string escapes each segment which doesn't match:
                // terminal ID: '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*;
                ids[i] = toEscapedString(id);
            }
        }
        return String.join(SEPARATOR, ids);
    }

    protected String toEscapedString(String value) {
        return '"' + Strings.convertToJavaString(value, false) + '"';
    }
}
