# Copyright 2017-2020 Palantir Technologies, Inc.
# Copyright 2021- Python Language Server Contributors.

import logging

from rope.base import libutils
from rope.refactor.rename import Rename

from pylsp import hookimpl, uris

log = logging.getLogger(__name__)


@hookimpl
def pylsp_settings():
    # Default rope_rename to disabled
    return {"plugins": {"rope_rename": {"enabled": False}}}


@hookimpl
def pylsp_rename(config, workspace, document, position, new_name):
    rope_config = config.settings(document_path=document.path).get("rope", {})
    rope_project = workspace._rope_project_builder(rope_config)

    rename = Rename(
        rope_project,
        libutils.path_to_resource(rope_project, document.path),
        document.offset_at_position(position),
    )

    log.debug(
        "Executing rename of %s to %s", document.word_at_position(position), new_name
    )
    changeset = rename.get_changes(new_name, in_hierarchy=True, docs=True)
    log.debug("Finished rename: %s", changeset.changes)
    changes = []
    for change in changeset.changes:
        uri = uris.from_fs_path(change.resource.path)
        doc = workspace.get_maybe_document(uri)
        changes.append(
            {
                "textDocument": {"uri": uri, "version": doc.version if doc else None},
                "edits": [
                    {
                        "range": {
                            "start": {"line": 0, "character": 0},
                            "end": {
                                "line": _num_lines(change.resource),
                                "character": 0,
                            },
                        },
                        "newText": change.new_contents,
                    }
                ],
            }
        )
    return {"documentChanges": changes}


def _num_lines(resource):
    "Count the number of lines in a `File` resource."
    return len(resource.read().splitlines())
