-- lx syntax
local syntax = require("core.syntax")
local quotes = require("core.quotes")

syntax.add({
	name = "JSON Document",
	shortname = "JSON",
	author = "liqube",

	extensions = {
		"json", "jsonc", "cjson", "ipynb", "cson"
	},
	comment = "//",

	patterns = {
		-- // line comment
		{ pattern = "//.-\n", type = "comment" },

		-- /* block comment */
		{ pattern = { "/%*", "%*/" }, type = "comment" },

		{ pattern = "[%{%}]", type = "label" }, -- braces

		-- Keys by container value kind:
		-- "key": { ... }
		-- "key": [ ... ]
		{
			pattern = { '"', '"', "\\" },
			type = "object",
			delim_type = "operator",
			followed_by = "%s*:%s*{",
			not_followed_by = "%s*.-%}",
		},
		{
			pattern = { '"', '"', "\\" },
			type = "array",
			delim_type = "operator",
			followed_by = "%s*:%s*%[",
			not_followed_by = "%s*.-%]",
		},

		-- Other keys: "key": <scalar>
		{ pattern = { '"', '"', "\\" }, type = "key", delim_type = "operator", followed_by = "%s*:" },

		-- Regular string literal values: "value"
		{ pattern = { '"', '"', "\\" }, type = "string", delim_type = "operator" },

		-- Hex number
		{ pattern = "0x[%da-fA-F]+", type = "hex" },

		-- Integer/float/exponent
		{ pattern = "-?%d+[%d%.eE]*", type = "number" },

		-- Fallback numeric form
		{ pattern = "-?%.?%d+", type = "number" },

		-- JSON punctuation
		{ pattern = "[{}:%[%],]", type = "operator" },

		-- Bare identifiers (true/false/null via symbols map)
		{ pattern = "[%a_][%w_]*", type = "symbol" },
	},

	-- Outline points for object-valued keys: "key": {
	outline_patterns = {
		{ pattern = '".-"%s*:%s*[%{%[]', not_followed_by = "%s*.-[%}%]]" },
	},

	quotes = {
		primary = "json",
		profiles = {
			json = {
				input_multiline = true,
				output_multiline = false,
				delimiters = '"',
				escape = quotes.escape.json_style(),
				unescape = quotes.unescape.json_style(),
			},
		},
	},

	symbols = {
		["true"] = "literal",
		["false"] = "literal",
		["null"] = "literal",
	},
})
