package org.jabref.logic.bibtex;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.jabref.logic.util.strings.StringUtil;
import org.jabref.model.entry.LinkedFile;

public class FileFieldWriter {

    private FileFieldWriter() {
    }

    public static String getStringRepresentation(List<LinkedFile> fields) {
        String[][] array = new String[fields.size()][];
        int i = 0;
        for (LinkedFile entry : fields) {
            if (StringUtil.isNullOrEmpty(entry.getSourceUrl())) {
                array[i] = new String[] {entry.getDescription(), entry.getLink(), entry.getFileType()};
            } else {
                array[i] = new String[] {entry.getDescription(), entry.getLink(), entry.getFileType(), entry.getSourceUrl()};
            }
            i++;
        }
        return encodeStringArray(array);
    }

    public static String getStringRepresentation(LinkedFile field) {
        return getStringRepresentation(List.of(field));
    }

    /// Encodes a two-dimensional String array into a single string, using ':' and
    /// ';' as separators. The characters ':' and ';' are escaped with '\'.
    ///
    /// @param values The String array.
    /// @return The encoded String.
    public static String encodeStringArray(String[][] values) {
        return Arrays.stream(values)
                     .map(FileFieldWriter::encodeStringArray)
                     .collect(Collectors.joining(";"));
    }

    /// Encodes a String array into a single string, using ':' as separator.
    /// The characters ':' and ';' are escaped with '\'.
    ///
    /// @param entry The String array.
    /// @return The encoded String.
    private static String encodeStringArray(String[] entry) {
        return Arrays.stream(entry)
                     .map(FileFieldWriter::quote)
                     .collect(Collectors.joining(":"));
    }

    public static String quote(String s) {
        if (s == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if ((c == ';') || (c == ':') || (c == '\\')) {
                sb.append('\\');
            }
            sb.append(c);
        }
        return sb.toString();
    }
}
