/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.internal.codegen;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * INTERNAL:
 * <p><b>Purpose</b>: Model a element of code generation purposes.
 *
 * @since TopLink 3.0
 * @author James Sutherland
 */
public abstract class CodeDefinition {
    protected AccessLevel accessLevel;
    protected String name;
    protected String comment;
    protected static final String JAVA_LANG_PACKAGE_NAME = "java.lang";
    protected static final String JAVA_UTIL_PACKAGE_NAME = "java.util";
    protected static final String TOPLINK_INDIRECTION_PACKAGE_NAME = "org.eclipse.persistence.indirection";

    protected CodeDefinition() {
        this.accessLevel = new AccessLevel();
        this.name = "";
        this.comment = "";
    }

    private static boolean adjustmentNeededForType(String typeName, Map typeNameMap) {
        if ((typeName == null) || typeName.equals("")) {
            return false;
        }

        if (packageName(typeName).length() == 0) {
            return false;
        }

        Set packages = (Set)typeNameMap.get(shortName(typeName));
        return (packages == null) || (packages.size() <= 1);
    }

    /**
     * Compares the typeName to those stored in the typeNameMap.
     * If the short name of the typeName is unambiguous (only one package for
     * that short name in the Map), removes the package name and returns the
     * short name, else returns the whole thing.
     *
     * Assumes that typeName contains only a package name (optional) and a short name,
     * potentially with subtended brackets.
     *
     * (e.g. int -&gt; int, java.util.Vector -&gt; Vector, java.lang.Boolean[] -&gt; Boolean[], etc.)
     */
    protected static String adjustTypeName(String typeName, Map typeNameMap) {
        if (adjustmentNeededForType(typeName, typeNameMap)) {
            putTypeNameInMap(typeName, typeNameMap);
            return typeName.substring(packageName(typeName).length() + 1);
        } else {
            return typeName;
        }
    }

    /**
     * Returns a set of java.lang.String type names included in longString.
     * Will only look for ValueHolder, java.util collection types, and TopLink
     * indirect collection types.
     * All other searches too intractable at this point.
     */
    protected static Set parseForTypeNames(String longString) {
        Set typeNames = new HashSet();

        if (longString != null) {
            typeNames.addAll(parseForTypeNamesInPackage(longString, JAVA_LANG_PACKAGE_NAME));
            typeNames.addAll(parseForTypeNamesInPackage(longString, JAVA_UTIL_PACKAGE_NAME));
            typeNames.addAll(parseForTypeNamesInPackage(longString, TOPLINK_INDIRECTION_PACKAGE_NAME));
        }

        return typeNames;
    }

    private static Set parseForTypeNamesInPackage(String longString, String packageName) {
        Set typeNames = new HashSet();
        int packageStartIndex = longString.indexOf(packageName);

        while (packageStartIndex != -1) {
            boolean lookingForEndOfTypeName = true;
            int searchIndex = packageStartIndex + packageName.length() + 1;

            while (lookingForEndOfTypeName) {
                if (Character.isJavaIdentifierPart(longString.charAt(searchIndex))) {
                    searchIndex++;
                } else {
                    lookingForEndOfTypeName = false;
                }
            }

            typeNames.add(longString.substring(packageStartIndex, searchIndex));
            packageStartIndex = longString.indexOf(packageName, searchIndex);
        }

        return typeNames;
    }

    /**
     * Used for calculating imports.  @see org.eclipse.persistence.internal.codegen.ClassDefinition#calculateImports()
     */
    protected static void putTypeNameInMap(String typeName, Map typeNameMap) {
        if ((typeName == null) || typeName.equals("")) {
            return;
        }

        String shortName = shortName(typeName);
        String packageName = packageName(typeName);

        if (packageName.length() > 0) {
            Set packageNames;

            if (typeNameMap.get(shortName) == null) {
                packageNames = new HashSet();
                typeNameMap.put(shortName, packageNames);
            } else {
                packageNames = (Set)typeNameMap.get(shortName);
            }

            // There is no package name.  The package is the default package.
            // Do nothing, as neither an import is needed, nor does the class need to be unqualified.
            if (!packageNames.contains(packageName)) {
                packageNames.add(packageName);
            }
        }
    }

    private static String packageName(String typeName) {
        int lastPeriod = typeName.lastIndexOf('.');

        if (lastPeriod == -1) {
            return "";
        } else {
            return typeName.substring(0, lastPeriod);
        }
    }

    /**
     * Removes the package name, if there is one.  Also removes any trailing brackets.
     *
     * Assumes that typeName contains only a package name (optional) and a short name,
     * potentially with subtended brackets.
     *
     * (e.g. int -> int, java.util.Vector -> Vector, java.lang.Boolean[] -> Boolean, etc.)
     */
    private static String shortName(String typeName) {
        int shortNameStartIndex = typeName.lastIndexOf('.') + 1;
        int searchIndex = shortNameStartIndex;

        boolean stillLookingForEnd = true;
        while (stillLookingForEnd) {
            if (Character.isJavaIdentifierPart(typeName.charAt(searchIndex))) {
                searchIndex++;
                stillLookingForEnd = searchIndex < typeName.length();
            } else {
                stillLookingForEnd = false;
            }
        }

        return typeName.substring(shortNameStartIndex, searchIndex);
    }

    public AccessLevel getAccessLevel() {
        return accessLevel;
    }

    public String getComment() {
        return comment;
    }

    public String getName() {
        return name;
    }

    public void setAccessLevel(AccessLevel accessLevel) {
        this.accessLevel = accessLevel;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        CodeGenerator generator = new CodeGenerator();
        write(generator);
        return generator.toString();
    }

    /**
     * Write the code out to the generator's stream.
     */
    public void write(CodeGenerator generator) {
        if (getComment().length() > 0) {
            generator.writeln("/**");
            String comment = getComment();
            String cr = org.eclipse.persistence.internal.helper.Helper.cr();
            int lastLineIndex = 0;
            int nextLineIndex = comment.indexOf(cr);
            while (nextLineIndex != -1) {
                generator.write(" * ");
                generator.write(comment.substring(lastLineIndex, nextLineIndex + cr.length()));
                lastLineIndex = nextLineIndex + cr.length();
                nextLineIndex = comment.indexOf(cr, lastLineIndex);
            }
            generator.write(" * ");
            generator.writeln(comment.substring(lastLineIndex, comment.length()));
            generator.writeln(" */");
            generator.cr();
        }
        getAccessLevel().write(generator);
        generator.write(" ");
        writeBody(generator);
    }

    /**
     * Write the code out to the generator's stream.
     */
    public abstract void writeBody(CodeGenerator generator);
}
