/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter Unisharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

package com.pullenti.unitext.internal.zip;

/**
 * ZipNameTransform transforms names as per the Zip file naming convention.
 */
public class ZipNameTransform implements INameTransform {

    /**
     * Initialize a new instance of <see cref="ZipNameTransform"></see>
     * @param _trimPrefix The string to trim from the front of paths if found.
     */
    public ZipNameTransform(String _trimPrefix) {
        setTrimPrefix(_trimPrefix);
    }


    /**
     * Transform a windows directory name according to the Zip file naming conventions.
     * @param name The directory name to transform.
     * @return The transformed name.
     */
    @Override
    public String transformDirectory(String name) {
        try {
            name = this.transformFile(name);
            if (name.length() > 0) {
                if (!name.endsWith("/")) 
                    name += "/";
            }
            else 
                throw new Exception("Cannot have an empty directory name");
            return name;
        } catch (Exception ex123) {
            return null;
        }
    }

    /**
     * Transform a windows file name according to the Zip file naming conventions.
     * @param name The file name to transform.
     * @return The transformed name.
     */
    @Override
    public String transformFile(String name) {
        try {
            if (name != null) {
                String lowerName = name.toLowerCase();
                if ((trimPrefix_ != null) && (lowerName.indexOf(trimPrefix_) == 0)) 
                    name = name.substring(trimPrefix_.length());
                name = name.replace("\\", "/");
                while ((name.length() > 0) && (name.charAt(0) == '/')) {
                    name = name.substring(1);
                }
                while ((name.length() > 0) && (name.charAt(name.length() - 1) == '/')) {
                    name = name.substring(0, 0 + name.length() - 1);
                }
                int index = name.indexOf("//");
                while (index >= 0) {
                    name = name.substring(0, 0 + index) + name.substring(index + 1);
                    index = name.indexOf("//");
                }
                name = makeValidName(name, '_');
            }
            else 
                name = "";
            return name;
        } catch (Exception ex123) {
            return null;
        }
    }

    public String getTrimPrefix() {
        return trimPrefix_;
    }

    public String setTrimPrefix(String value) {
        trimPrefix_ = value;
        if (trimPrefix_ != null) 
            trimPrefix_ = trimPrefix_.toLowerCase();
        return value;
    }


    /**
     * Force a name to be valid by replacing invalid characters with a fixed value
     * @param name The name to force valid
     * @param replacement The replacement character to use.
     * @return Returns a valid name
     */
    private static String makeValidName(String name, char replacement) throws Exception {
        int index = com.pullenti.unisharp.Utils.indexOfAny(name, invalidEntryChars, 0, 0);
        if (index >= 0) {
            StringBuilder builder = new StringBuilder(name);
            while (index >= 0) {
                builder.setCharAt(index, replacement);
                if (index >= name.length()) 
                    index = -1;
                else 
                    index = com.pullenti.unisharp.Utils.indexOfAny(name, invalidEntryChars, index + 1, 0);
            }
            name = builder.toString();
        }
        if (name.length() > 0xffff) 
            throw new Exception("PathTooLong");
        return name;
    }

    /**
     * Test a name to see if it is a valid name for a zip entry.
     * @param name The name to test.
     * @param relaxed If true checking is relaxed about windows file names and absolute paths.
     * @return Returns true if the name is a valid zip name; false otherwise.
     */
    public static boolean isValidNameEx(String name, boolean relaxed) {
        boolean result = name != null;
        if (result) {
            if (relaxed) 
                result = com.pullenti.unisharp.Utils.indexOfAny(name, invalidEntryCharsRelaxed, 0, 0) < 0;
            else 
                result = ((com.pullenti.unisharp.Utils.indexOfAny(name, invalidEntryChars, 0, 0) < 0)) && (name.indexOf('/') != 0);
        }
        return result;
    }

    /**
     * Test a name to see if it is a valid name for a zip entry.
     * @param name The name to test.
     * @return Returns true if the name is a valid zip name; false otherwise.
     */
    public static boolean isValidName(String name) {
        boolean result = (name != null) && ((com.pullenti.unisharp.Utils.indexOfAny(name, invalidEntryChars, 0, 0) < 0)) && (name.indexOf('/') != 0);
        return result;
    }

    private String trimPrefix_;

    private static char[] invalidEntryChars;

    private static char[] invalidEntryCharsRelaxed;
    public ZipNameTransform() {
        this(null);
    }
    
    static {
        char[] invalidPathChars;
        invalidPathChars = new char[0];
        int howMany = invalidPathChars.length + 2;
        invalidEntryCharsRelaxed = new char[howMany];
        for(int iii = 0; iii < (invalidPathChars.length); iii++) invalidEntryCharsRelaxed[(0) + iii] = invalidPathChars[(0) + iii];
        invalidEntryCharsRelaxed[howMany - 1] = '*';
        invalidEntryCharsRelaxed[howMany - 2] = '?';
        howMany = invalidPathChars.length + 4;
        invalidEntryChars = new char[howMany];
        for(int iii = 0; iii < (invalidPathChars.length); iii++) invalidEntryChars[(0) + iii] = invalidPathChars[(0) + iii];
        invalidEntryChars[howMany - 1] = ':';
        invalidEntryChars[howMany - 2] = '\\';
        invalidEntryChars[howMany - 3] = '*';
        invalidEntryChars[howMany - 4] = '?';
    }
}
