#!python
#
# Copyright (c) 2012-2025 Snowflake Computing Inc. All rights reserved.
#

"""
CLI tool for creating a Snowflake Python stored procedure that calls a Java/Scala
class's ``main(String[] args)`` method via the SCOS server.

Thin wrapper around the programmatic API in
``snowflake.snowpark_connect.orchestration.sproc_manager``.

Examples:

  # Basic: create a stored procedure for a class
  snowpark-connect-create-jvm-sproc \\
      --class-name com.example.MyApp \\
      --jars app.jar

  # Custom procedure name + replace if exists
  snowpark-connect-create-jvm-sproc \\
      --class-name com.example.MyApp \\
      --jars app.jar,dep1.jar \\
      --procedure-name MY_PROC \\
      --replace

  # Glob patterns for JARs
  snowpark-connect-create-jvm-sproc \\
      --class-name com.example.MyApp \\
      --jars "target/scala-2.12/*.jar,lib/*.jar"

  # Dry run: print the full setup script (CREATE STAGE + PUT statements +
  # CREATE PROCEDURE) without executing anything against Snowflake. The
  # output can be copy-pasted into a Snowflake worksheet.
  snowpark-connect-create-jvm-sproc \\
      --class-name com.example.MyApp \\
      --jars app.jar \\
      --dry-run
"""

import argparse
import logging
import sys

logger = logging.getLogger("snowpark-connect-create-jvm-sproc")


def main():
    parser = argparse.ArgumentParser(
        description=(
            "Create a Snowflake stored procedure that calls a Java/Scala "
            "class's main(String[] args) method."
        ),
        epilog=(
            "Examples:\n\n"
            "  # Basic\n"
            "  snowpark-connect-create-jvm-sproc \\\n"
            "      --class-name com.example.MyApp \\\n"
            "      --jars app.jar\n\n"
            "  # With glob patterns and --replace\n"
            "  snowpark-connect-create-jvm-sproc \\\n"
            "      --class-name com.example.MyApp \\\n"
            '      --jars "target/*.jar,lib/*.jar" \\\n'
            "      --replace\n\n"
            "  # Dry run\n"
            "  snowpark-connect-create-jvm-sproc \\\n"
            "      --class-name com.example.MyApp \\\n"
            "      --jars app.jar \\\n"
            "      --dry-run\n"
        ),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "--class-name",
        required=True,
        help="Fully qualified Java/Scala class name (e.g. com.example.MyApp).",
    )
    parser.add_argument(
        "--jars",
        required=True,
        help="Comma-separated JAR files or glob patterns (at least one required).",
    )
    parser.add_argument(
        "--procedure-name",
        default=None,
        help="Snowflake procedure name. Defaults to <SimpleClassName>_main.",
    )
    parser.add_argument(
        "--replace",
        action="store_true",
        help="Use CREATE OR REPLACE PROCEDURE (overwrites existing).",
    )
    parser.add_argument(
        "--dry-run",
        action="store_true",
        help="Print the full setup script (CREATE STAGE + PUT + CREATE "
        "PROCEDURE) without executing anything against Snowflake.",
    )
    parser.add_argument(
        "--snowpark-connect-version",
        default=None,
        help="Pin snowpark-connect to a specific version (e.g. '1.21.1'). "
        "If not set, uses the latest available in Anaconda.",
    )
    parser.add_argument(
        "--verbose",
        action="store_true",
        help="Enable verbose (DEBUG) logging.",
    )

    args = parser.parse_args()

    log_level = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(
        level=log_level,
        format="%(asctime)s %(levelname)s [%(name)s] %(message)s",
    )

    from snowflake.snowpark_connect.orchestration.sproc_manager import (
        create_jvm_sproc,
        resolve_jars,
    )

    try:
        jar_files = resolve_jars(args.jars.split(","))
        logger.info(
            f"Resolved {len(jar_files)} JAR(s): "
            f"{[__import__('os').path.basename(j) for j in jar_files]}"
        )

        sql = create_jvm_sproc(
            class_name=args.class_name,
            jar_files=jar_files,
            procedure_name=args.procedure_name,
            replace=args.replace,
            dry_run=args.dry_run,
            snowpark_connect_version=args.snowpark_connect_version,
        )

        if args.dry_run:
            print(sql)  # noqa: T201

    except (FileNotFoundError, ValueError, TypeError, RuntimeError) as e:
        logger.error(str(e))
        sys.exit(1)


if __name__ == "__main__":
    main()
