-- All-in-one Neovim config for EVM Assembly with Tree-sitter
-- Usage: nvim -u all-in-one-nvim-config.lua example.eas

-- Ensure we have a clean environment
vim.cmd('set nocompatible')
vim.cmd('syntax enable')

-- Basic settings
vim.opt.number = true
vim.opt.relativenumber = true
vim.opt.expandtab = true
vim.opt.shiftwidth = 4
vim.opt.tabstop = 4

-- Set up paths
local data_path = vim.fn.stdpath('data')
local pack_path = data_path .. '/site/pack/packer/start'
vim.opt.runtimepath:prepend(pack_path .. '/nvim-treesitter')
vim.opt.runtimepath:prepend(pack_path .. '/nvim-lspconfig')

-- Add tree-sitter-evm-asm to runtime path
local evm_asm_path = vim.fn.expand('~/projects/evm-asm-lsp/crates/tree-sitter-evm-asm')
vim.opt.runtimepath:append(evm_asm_path)

-- Filetype detection
vim.filetype.add({
  extension = {
    eas = 'evmasm',
    evm = 'evmasm',
    evmasm = 'evmasm',
  }
})

-- Check and setup Tree-sitter
local function setup_treesitter()
  local ok, ts_configs = pcall(require, 'nvim-treesitter.configs')
  if not ok then
    print("Tree-sitter not installed. Run:")
    print("git clone https://github.com/nvim-treesitter/nvim-treesitter " .. pack_path .. "/nvim-treesitter")
    return false
  end
  
  -- Register our parser
  local parsers = require('nvim-treesitter.parsers')
  local parser_config = parsers.get_parser_configs()
  
  parser_config.evm_asm = {
    install_info = {
      url = evm_asm_path,
      files = {"src/parser.c"},
      generate_requires_npm = false,
      requires_generate_from_grammar = false,
    },
    filetype = "evmasm",
  }
  
  -- Configure Tree-sitter
  ts_configs.setup({
    ensure_installed = {},
    highlight = {
      enable = true,
      disable = function(lang, buf)
        -- Never disable for our language
        return lang ~= "evm_asm"
      end,
    },
    indent = { enable = true },
  })
  
  -- Ensure queries can be found
  local queries_dir = pack_path .. '/nvim-treesitter/queries/evm_asm'
  if vim.fn.isdirectory(queries_dir) == 0 then
    local target = evm_asm_path .. '/queries'
    vim.fn.system({'ln', '-sf', target, queries_dir})
  end
  
  return true
end

-- Check and setup LSP
local function setup_lsp()
  local ok, lspconfig = pcall(require, 'lspconfig')
  if not ok then
    print("LSP not installed. Run:")
    print("git clone https://github.com/neovim/nvim-lspconfig " .. pack_path .. "/nvim-lspconfig")
    return false
  end
  
  local configs = require('lspconfig.configs')
  configs.evm_asm_lsp = {
    default_config = {
      cmd = { vim.fn.expand('~/projects/evm-asm-lsp/target/release/evm-asm-lsp') },
      filetypes = { 'evmasm' },
      root_dir = function() return vim.fn.getcwd() end,
    },
  }
  
  lspconfig.evm_asm_lsp.setup({
    on_attach = function(_, bufnr)
      local opts = { buffer = bufnr, noremap = true, silent = true }
      vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
      vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
      vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
      vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
      vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, opts)
    end,
  })
  
  return true
end

-- Auto-commands
vim.api.nvim_create_autocmd('FileType', {
  pattern = 'evmasm',
  callback = function(ev)
    -- Try to start LSP
    pcall(vim.lsp.start, {
      name = 'evm-asm-lsp',
      cmd = { vim.fn.expand('~/projects/evm-asm-lsp/target/release/evm-asm-lsp') },
      root_dir = vim.fn.getcwd(),
    })
    
    -- Force Tree-sitter highlighting
    vim.defer_fn(function()
      if require('nvim-treesitter.parsers').has_parser('evm_asm') then
        vim.cmd('TSBufEnable highlight')
      end
    end, 100)
  end,
})

-- User commands
vim.api.nvim_create_user_command('EVMInfo', function()
  print("=== EVM Assembly Environment ===")
  print("Filetype: " .. vim.bo.filetype)
  
  local has_ts = pcall(require, 'nvim-treesitter')
  print("Tree-sitter available: " .. tostring(has_ts))
  
  if has_ts then
    local has_parser = require('nvim-treesitter.parsers').has_parser('evm_asm')
    print("EVM parser installed: " .. tostring(has_parser))
  end
  
  local has_lsp = #vim.lsp.get_active_clients() > 0
  print("LSP active: " .. tostring(has_lsp))
  
  print("\nIf parser not installed, run: :TSInstall evm_asm")
end, {})

-- Initialize
local ts_ok = setup_treesitter()
local lsp_ok = setup_lsp()

-- Status message
vim.defer_fn(function()
  print("EVM Assembly environment loaded!")
  print("Tree-sitter: " .. (ts_ok and "✓" or "✗"))
  print("LSP: " .. (lsp_ok and "✓" or "✗"))
  print("")
  if ts_ok and not require('nvim-treesitter.parsers').has_parser('evm_asm') then
    print("Run :TSInstall evm_asm to install the parser")
  end
  print("Run :EVMInfo for status")
end, 100)

-- Keymaps info
vim.keymap.set('n', '<F1>', function()
  print([[
EVM Assembly Keybindings:
  K          - Show hover info
  gd         - Go to definition
  gr         - Find references
  <space>rn  - Rename
  <space>ca  - Code actions
  <F1>       - Show this help
  :EVMInfo   - Show environment info
  ]])
end, { desc = "Show EVM Assembly keybindings" })