/*
 * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.jshell;

import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * Provides analysis utilities for source code input.
 * Optional functionality that provides for a richer interactive experience.
 * Includes completion analysis:
 * Is the input a complete snippet of code?
 * Do I need to prompt for more input?
 * Would adding a semicolon make it complete?
 * Is there more than one snippet?
 * etc.
 * Also includes completion suggestions, as might be used in tab-completion.
 *
 * @since 9
 */
public abstract class SourceCodeAnalysis {

    /**
     * Given an input string, find the first snippet of code (one statement,
     * definition, import, or expression) and evaluate if it is complete.
     * @param input the input source string
     * @return a CompletionInfo instance with location and completeness info
     */
    public abstract CompletionInfo analyzeCompletion(String input);

    /**
     * Compute possible follow-ups for the given input.
     * Uses information from the current {@code JShell} state, including
     * type information, to filter the suggestions.
     * @param input the user input, so far
     * @param cursor the current position of the cursors in the given {@code input} text
     * @param anchor outgoing parameter - when an option will be completed, the text between
     *               the anchor and cursor will be deleted and replaced with the given option
     * @return list of candidate continuations of the given input.
     */
    public abstract List<Suggestion> completionSuggestions(String input, int cursor, int[] anchor);

    /**
     * Compute documentation for the given user's input. Multiple {@code Documentation} objects may
     * be returned when multiple elements match the user's input (like for overloaded methods).
     * @param input the snippet the user wrote so far
     * @param cursor the current position of the cursors in the given {@code input} text
     * @param computeJavadoc true if the javadoc for the given input should be computed in
     *                       addition to the signature
     * @return the documentations for the given user's input, if multiple elements match the input,
     *         multiple {@code Documentation} objects are returned.
     */
    public abstract List<Documentation> documentation(String input, int cursor, boolean computeJavadoc);

    /**
     * Infer the type of the given expression. The expression spans from the beginning of {@code code}
     * to the given {@code cursor} position. Returns null if the type of the expression cannot
     * be inferred.
     *
     * @param code the expression for which the type should be inferred
     * @param cursor current cursor position in the given code
     * @return the inferred type, or null if it cannot be inferred
     */
    public abstract String analyzeType(String code, int cursor);

    /**
     * List qualified names known for the simple name in the given code immediately
     * to the left of the given cursor position. The qualified names are gathered by inspecting the
     * classpath used by eval (see {@link JShell#addToClasspath(java.lang.String)}).
     *
     * @param code the expression for which the candidate qualified names should be computed
     * @param cursor current cursor position in the given code
     * @return the known qualified names
     */
    public abstract QualifiedNames listQualifiedNames(String code, int cursor);

    /**
     * Returns the wrapper information for the {@code Snippet}. The wrapper changes as
     * the environment changes, so calls to this method at different times may
     * yield different results.
     *
     * @param snippet the {@code Snippet} from which to retrieve the wrapper
     * @return information on the wrapper
     */
    public abstract SnippetWrapper wrapper(Snippet snippet);

    /**
     * Returns the wrapper information for the snippet within the
     * input source string.
     * <p>
     * Wrapper information for malformed and incomplete
     * snippets also generate wrappers. The list is in snippet encounter
     * order. The wrapper changes as the environment changes, so calls to this
     * method at different times may yield different results.
     * <p>
     * The input should be
     * exactly one complete snippet of source code, that is, one expression,
     * statement, variable declaration, method declaration, class declaration,
     * or import.
     * To break arbitrary input into individual complete snippets, use
     * {@link SourceCodeAnalysis#analyzeCompletion(String)}.
     * <p>
     * The wrapper may not match that returned by
     * {@link SourceCodeAnalysis#wrapper(Snippet) wrapper(Snippet)},
     * were the source converted to a {@code Snippet}.
     *
     * @param input the source input from which to generate wrappers
     * @return a list of wrapper information
     */
    public abstract List<SnippetWrapper> wrappers(String input);

    /**
     * Converts the source code of a snippet into a {@link Snippet} object (or
     * list of {@code Snippet} objects in the case of some var declarations,
     * e.g.: int x, y, z;).
     * Does not install the snippets: declarations are not
     * accessible by other snippets; imports are not added.
     * Does not execute the snippets.
     * <p>
     * Queries may be done on the {@code Snippet} object. The {@link Snippet#id()}
     * will be {@code "*UNASSOCIATED*"}.
     * The returned snippets are not associated with the
     * {@link JShell} instance, so attempts to pass them to {@code JShell}
     * methods will throw an {@code IllegalArgumentException}, unless otherwise
     * noted.
     * They will not appear in queries for snippets --
     * for example, {@link JShell#snippets() }.
     * <p>
     * Restrictions on the input are as in {@link JShell#eval(String)}.
     * <p>
     * Only preliminary compilation is performed, sufficient to build the
     * {@code Snippet}.  Snippets known to be erroneous, are returned as
     * {@link ErroneousSnippet}, other snippets may or may not be in error.
     *
     * @param input The input String to convert
     * @return usually a singleton list of Snippet, but may be empty or multiple
     * @throws IllegalStateException if the {@code JShell} instance is closed.
     *
     * @since 10
     */
    public abstract List<Snippet> sourceToSnippets(String input);

    /**
     * Returns a collection of {@code Snippet}s which might need updating if the
     * given {@code Snippet} is updated. The returned collection is designed to
     * be inclusive and may include many false positives.
     *
     * @param snippet the {@code Snippet} whose dependents are requested
     * @return the collection of dependents
     */
    public abstract Collection<Snippet> dependents(Snippet snippet);

    /**
     * Returns a collection of {@code Highlight}s which can be used to color
     * the given snippet.
     * <p>
     * The returned {@code Highlight}s do not overlap, and are sorted by their
     * start position.
     *
     * @param snippet the snippet for which the {@code Highlight}s should be computed
     * @return the computed {@code Highlight}s.
     * @since 19
     */
    public abstract List<Highlight> highlights(String snippet);

    /**
     * Internal only constructor
     */
    SourceCodeAnalysis() {}

    /**
     * The result of {@code analyzeCompletion(String input)}.
     * Describes the completeness of the first snippet in the given input.
     */
    public interface CompletionInfo {

        /**
         * The analyzed completeness of the input.
         *
         * @return an enum describing the completeness of the input string.
         */
        Completeness completeness();

        /**
         * Input remaining after the complete part of the source.
         *
         * @return the portion of the input string that remains after the
         * complete Snippet
         */
        String remaining();

        /**
         * Source code for the first Snippet of code input. For example, first
         * statement, or first method declaration. Trailing semicolons will be
         * added, as needed.
         *
         * @return the source of the first encountered Snippet
         */
        String source();
    }

    /**
     * Describes the completeness of the given input.
     */
    public enum Completeness {
        /**
         * The input is a complete source snippet (declaration or statement) as is.
         */
        COMPLETE(true),

        /**
         * With this addition of a semicolon the input is a complete source snippet.
         * This will only be returned when the end of input is encountered.
         */
        COMPLETE_WITH_SEMI(true),

        /**
         * There must be further source beyond the given input in order for it
         * to be complete.  A semicolon would not complete it.
         * This will only be returned when the end of input is encountered.
         */
        DEFINITELY_INCOMPLETE(false),

        /**
         * A statement with a trailing (non-terminated) empty statement.
         * Though technically it would be a complete statement
         * with the addition of a semicolon, it is rare
         * that that assumption is the desired behavior.
         * The input is considered incomplete.  Comments and white-space are
         * still considered empty.
         */
        CONSIDERED_INCOMPLETE(false),


        /**
         * An empty input.
         * The input is considered incomplete.  Comments and white-space are
         * still considered empty.
         */
        EMPTY(false),

        /**
         * The completeness of the input could not be determined because it
         * contains errors. Error detection is not a goal of completeness
         * analysis, however errors interfered with determining its completeness.
         * The input is considered complete because evaluating is the best
         * mechanism to get error information.
         */
        UNKNOWN(true);

        private final boolean isComplete;

        Completeness(boolean isComplete) {
            this.isComplete = isComplete;
        }

        /**
         * Indicates whether the first snippet of source is complete.
         * For example, "{@code x=}" is not
         * complete, but "{@code x=2}" is complete, even though a subsequent line could
         * make it "{@code x=2+2}". Already erroneous code is marked complete.
         *
         * @return {@code true} if the input is or begins a complete Snippet;
         * otherwise {@code false}
         */
        public boolean isComplete() {
            return isComplete;
        }
    }

    /**
     * A candidate for continuation of the given user's input.
     */
    public interface Suggestion {

        /**
         * The candidate continuation of the given user's input.
         *
         * @return the continuation string
         */
        String continuation();

        /**
         * Indicates whether input continuation matches the target type and is thus
         * more likely to be the desired continuation. A matching continuation is
         * preferred.
         *
         * @return {@code true} if this suggested continuation matches the
         * target type; otherwise {@code false}
         */
        boolean matchesType();
    }

    /**
     * A documentation for a candidate for continuation of the given user's input.
     */
    public interface Documentation {

        /**
         * The signature of the given element.
         *
         * @return the signature
         */
        String signature();

        /**
         * The javadoc of the given element.
         *
         * @return the javadoc, or null if not found or not requested
         */
        String javadoc();
    }

    /**
     * List of possible qualified names.
     */
    public static final class QualifiedNames {

        private final List<String> names;
        private final int simpleNameLength;
        private final boolean upToDate;
        private final boolean resolvable;

        QualifiedNames(List<String> names, int simpleNameLength, boolean upToDate, boolean resolvable) {
            this.names = names;
            this.simpleNameLength = simpleNameLength;
            this.upToDate = upToDate;
            this.resolvable = resolvable;
        }

        /**
         * Known qualified names for the given simple name in the original code.
         *
         * @return known qualified names
         */
        public List<String> getNames() {
            return names;
        }

        /**
         * The length of the simple name in the original code for which the
         * qualified names where gathered.
         *
         * @return the length of the simple name; -1 if there is no name immediately left to the cursor for
         *         which the candidates could be computed
         */
        public int getSimpleNameLength() {
            return simpleNameLength;
        }

        /**
         * Indicates whether the result is based on up-to-date data. The
         * {@link SourceCodeAnalysis#listQualifiedNames(java.lang.String, int) listQualifiedNames}
         * method may return before the classpath is fully inspected, in which case this method will
         * return {@code false}. If the result is based on a fully inspected classpath, this method
         * will return {@code true}.
         *
         * @return {@code true} if the result is based on up-to-date data;
         * otherwise {@code false}
         */
        public boolean isUpToDate() {
            return upToDate;
        }

        /**
         * Indicates whether the given simple name in the original code refers
         * to a resolvable element.
         *
         * @return {@code true} if the given simple name in the original code
         * refers to a resolvable element; otherwise {@code false}
         */
        public boolean isResolvable() {
            return resolvable;
        }

    }

    /**
     * The wrapping of a snippet of Java source into valid top-level Java
     * source. The wrapping will always either be an import or include a
     * synthetic class at the top-level. If a synthetic class is generated, it
     * will be proceeded by the package and import declarations, and may contain
     * synthetic class members.
     * <p>
     * This interface, in addition to the mapped form, provides the context and
     * position mapping information.
     */
    public interface SnippetWrapper {

        /**
         * Returns the input that is wrapped. For
         * {@link SourceCodeAnalysis#wrappers(java.lang.String) wrappers(String)},
         * this is the source of the snippet within the input. A variable
         * declaration of {@code N} variables will map to {@code N} wrappers
         * with the source separated.
         * <p>
         * For {@link SourceCodeAnalysis#wrapper(Snippet) wrapper(Snippet)},
         * this is {@link Snippet#source() }.
         *
         * @return the input source corresponding to the wrapper.
         */
        String source();

        /**
         * Returns a Java class definition that wraps the
         * {@link SnippetWrapper#source()} or, if an import, the import source.
         * <p>
         * If the input is not a valid Snippet, this will not be a valid
         * class/import definition.
         * <p>
         * The source may be divided and mapped to different locations within
         * the wrapped source.
         *
         * @return the source wrapped into top-level Java code
         */
        String wrapped();

        /**
         * Returns the fully qualified class name of the
         * {@link SnippetWrapper#wrapped() } class.
         * For erroneous input, a best guess is returned.
         *
         * @return the name of the synthetic wrapped class; if an import, the
         * name is not defined
         */
        String fullClassName();

        /**
         * Returns the {@link Snippet.Kind} of the
         * {@link SnippetWrapper#source()}.
         *
         * @return an enum representing the general kind of snippet.
         */
        Snippet.Kind kind();

        /**
         * Maps character position within the source to character position
         * within the wrapped.
         *
         * @param pos the position in {@link SnippetWrapper#source()}
         * @return the corresponding position in
         * {@link SnippetWrapper#wrapped() }
         */
        int sourceToWrappedPosition(int pos);

        /**
         * Maps character position within the wrapped to character position
         * within the source.
         *
         * @param pos the position in {@link SnippetWrapper#wrapped()}
         * @return the corresponding position in
         * {@link SnippetWrapper#source() }
         */
        int wrappedToSourcePosition(int pos);
    }

    /**Assigns attributes usable for coloring to spans inside a snippet.
     *
     * @param start the starting position of the span
     * @param end the ending position of the span
     * @param attributes the attributes assigned to the span
     * @since 19
     */
    public record Highlight(int start, int end, Set<Attribute> attributes) {}

    /**
     * A span attribute which can be used to derive a coloring.
     * @since 19
     */
    public enum Attribute {
        /**
         * The span refers to a declaration of an element.
         */
        DECLARATION,
        /**
         * The span refers to a deprecated element.
         */
        DEPRECATED,
        /**
         * The span is a keyword.
         */
        KEYWORD;
    }
}
