-- lx format
local format = require("core.format")
local java_references = require("format.java.references")

format.register({
	name = "Java",
	shortname = "Java",
	author = "liqube",
	extensions = "java",
	comment = "//",
	file_references = java_references.new(),

	patterns = {
		{ pattern = "//.-\n", type = "comment" },
		{ pattern = { "/%*", "%*/" }, type = "comment" },
		{
			pattern = "%s*(package%s+[%w_%.%*]+%s*;)(%s*\n)",
			type = { "meta", "operator" },
			line_start = true
		},
		{
			pattern = "%s*(import)%s+([%w_%.%*]+)%s*(;%s*\n)",
			type = { "keyword", "normal", "operator" },
			line_start = true,
		},
		{ pattern = { '"', '"', "\\" }, type = "string", delim_type = "operator" },
		{ pattern = { "'", "'", "\\" }, type = "string", delim_type = "operator" },

		{ pattern = "non%-sealed", type = "keyword" },
		{ pattern = "@[%a_][%w_]*", type = "keyword2" }, -- annotations
		{ pattern = "0[bB][01][01_]*[lL]?", type = "number" },
		{ pattern = "0[xX][%da-fA-F][%da-fA-F_]*[lL]?", type = "number" },
		{ pattern = "%d[%d_]*%.%d[%d_]*[eE][%+%-]?%d[%d_]*[fFdD]?", type = "number" },
		{ pattern = "%d[%d_]*%.%d[%d_]*[fFdD]?", type = "number" },
		{ pattern = "%d[%d_]*[eE][%+%-]?%d[%d_]*[fFdD]?", type = "number" },
		{ pattern = "%d[%d_]*[fFdDlL]?", type = "number" },
		{ pattern = "%f[%a_][A-Z][A-Z0-9_]*%f[^%w_]", type = "keyword2" }, -- all-caps constants (whole identifier)
		{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
		{ pattern = "[%+%-=/%*%^%%<>!~|&%?:;,.%(%)%[%]{}]", type = "operator" },
		{ pattern = "[%a_][%w_]*", type = "symbol" },
	},

	block_comment = {
		block_open = "/*",
		block_close = "*/",
		block_line_prefix = " * ",
		close_line_prefix = " ",
		open_on_own_line = false,
		close_on_own_line = true,
		strip_line_prefix = "^%s*%*%s?",
		allow_nested = false,
	},

	symbols = {
		-- Control Flow
		["break"] = "keyword", -- Exit loops or switch blocks
		["case"] = "keyword", -- Switch block label
		["continue"] = "keyword", -- Skip to next loop iteration
		["default"] = "keyword", -- Fallback for switch or interface methods
		["do"] = "keyword", -- Start of do-while loop
		["else"] = "keyword", -- Alternative branch for if-statements
		["finally"] = "keyword", -- Block that always executes after try-catch
		["for"] = "keyword", -- Standard and enhanced for-loops
		["if"] = "keyword", -- Conditional branch
		["return"] = "keyword", -- Exit method and return value
		["switch"] = "keyword", -- Multi-way branch
		["while"] = "keyword", -- Standard while loop
		["yield"] = "keyword", -- Return value from switch expression

		-- Declarations and Access Modifiers
		["abstract"] = "keyword", -- Class or method without implementation
		["class"] = "keyword", -- Define a class
		["enum"] = "keyword", -- Define an enumeration
		["extends"] = "keyword", -- Subclassing or interface extension
		["final"] = "keyword", -- Non-modifiable variable/class/method
		["implements"] = "keyword", -- Interface implementation
		["interface"] = "keyword", -- Define an interface
		["native"] = "keyword", -- Method implemented in JNI/C++
		["new"] = "keyword", -- Instantiate an object
		["package"] = "keyword", -- Define the namespace
		["private"] = "keyword", -- Restricted to the class
		["protected"] = "keyword", -- Accessible to subclasses/package
		["public"] = "keyword", -- Accessible everywhere
		["static"] = "keyword", -- Class-level member
		["strictfp"] = "keyword", -- Strict floating-point math (obsolete)
		["synchronized"] = "keyword", -- Thread-safe block or method
		["transient"] = "keyword", -- Field not included in serialization
		["volatile"] = "keyword", -- Field requiring atomic visibility

		-- Exception Handling
		["assert"] = "keyword", -- Debugging check
		["catch"] = "keyword", -- Handle exception
		["throw"] = "keyword", -- Explicitly throw exception
		["throws"] = "keyword", -- Declare exceptions in signature
		["try"] = "keyword", -- Start of error-handling block

		-- Modern and Contextual Keywords (Java 11..21+)
		["non-sealed"] = "keyword", -- Hierarchy exit for sealed classes
		["permits"] = "keyword", -- Explicitly allowed subclasses
		["record"] = "keyword", -- Immutable data carrier (Java 14+)
		["sealed"] = "keyword", -- Restrict class hierarchies (Java 15+)
		["var"] = "keyword", -- Local variable type inference
		["when"] = "keyword", -- Guard clause in patterns (Java 21+)
		["_"] = "keyword", -- Unnamed variable/pattern (Java 21+)

		-- Module System (Java 9+)
		["exports"] = "keyword",
		["module"] = "keyword",
		["open"] = "keyword",
		["opens"] = "keyword",
		["provides"] = "keyword",
		["requires"] = "keyword",
		["to"] = "keyword",
		["transitive"] = "keyword",
		["uses"] = "keyword",
		["with"] = "keyword",

		-- Object Reference
		["instanceof"] = "keyword", -- Runtime type checking
		["super"] = "keyword", -- Reference parent class
		["this"] = "keyword", -- Reference current instance

		-- Reserved (Unused)
		["const"] = "keyword", -- Reserved for future use
		["goto"] = "keyword", -- Reserved for future use

		-- Basic Types
		["boolean"] = "keyword2",
		["byte"] = "keyword2",
		["char"] = "keyword2",
		["double"] = "keyword2",
		["float"] = "keyword2",
		["int"] = "keyword2",
		["long"] = "keyword2",
		["short"] = "keyword2",
		["void"] = "keyword2",

		-- Literals
		["false"] = "literal",
		["null"] = "literal",
		["true"] = "literal",
	},
})
