(require 'common-lsp)
(require 'util-tree-sitter)

(defun python-backspace (arg)
  "Special handling of python backspace."
  (interactive "*p")
  (if mark-active
      (backward-delete-char-untabify arg)
    (python-indent-dedent-line-backspace arg)
    )
  )

(defun locate-venv-poetry ()
  "Find a poetry venv."
  (run-command-in-directory nil "poetry" "env" "info" "-p")
  )

(defun locate-pyproject-directory ()
  "Adapt lsp-python-ms for poetry."
  (let ((pypoetry-file (locate-dominating-file (buffer-file-name) "pyproject.toml")))
    pypoetry-file
    )
  )


(defun python-fmt ()
  "format python."
  (python-fmt-black)
  (python-fmt-isort)
  )

(defun python-fmt-black ()
  "Run black."
  (run-command-on-buffer "black" "--quiet" "--fast" "-")
  )

(defun python-fmt-isort ()
  "Run isort."
  (run-command-on-buffer "isort" "-")
  )

(defun add-poetry-venv-to-path ()
  "Add the bin folder in the poetry venv to exec-path."
  (let (
        (venv-path (locate-venv-poetry))
        )
    (when venv-path
      (make-local-variable 'exec-path)
      (add-to-list 'exec-path (concat venv-path "/bin"))
      )
    )
  )

(use-package python
  :mode ("\\.py\\'" . python-ts-mode)
  :commands (python-mode python-ts-mode)
  :pin manual
  :hook (
         (python-ts-mode . (lambda ()
                             (when-linux
                               (when (executable-find "poetry")
                                 (add-poetry-venv-to-path)
                                 (let ((venv (locate-venv-poetry))) (when venv
                                                                      (setq eglot-workspace-configuration
                                                                            (list (cons ':python (list ':venvPath venv ':pythonPath (concat venv "/bin/python")))))
                                                                      ))
                                 )
                               (eglot-ensure)
                               )

                             ;; (when-freebsd
                             ;;   (eglot-ensure)
                             ;;   (defclass my/eglot-pylyzer (eglot-lsp-server) ()
                             ;;     :documentation
                             ;;     "Own eglot server class.")

                             ;;   (add-to-list 'eglot-server-programs
                             ;;                '(python-ts-mode . (my/eglot-pylyzer "pylyzer" "--server")))
                             ;;   )

                             (add-hook 'before-save-hook 'python-fmt nil 'local)
                             ))
         )
  :bind ((:map python-ts-mode-map ([backspace] . python-backspace))
         )
  :init
  (add-to-list 'major-mode-remap-alist '(python-mode . python-ts-mode))
  (add-to-list 'treesit-language-source-alist '(python "https://github.com/tree-sitter/tree-sitter-python"))
  (unless (treesit-ready-p 'python) (treesit-install-language-grammar 'python))
  )

(provide 'lang-python)