import sys
import ast

def get_slice(filepath: str, start_line: int | str, end_line: int | str) -> str:
 with open(filepath, 'r', encoding='utf-8') as f:
  lines = f.readlines()
 start_idx = int(start_line) - 1
 end_idx = int(end_line)
 return "".join(lines[start_idx:end_idx])

def set_slice(filepath: str, start_line: int | str, end_line: int | str, new_content: str) -> None:
 with open(filepath, 'r', encoding='utf-8') as f:
  lines = f.readlines()
 start_idx = int(start_line) - 1
 end_idx = int(end_line)
 if new_content and not new_content.endswith(chr(10)):
  new_content += chr(10)
 new_lines = new_content.splitlines(True) if new_content else []
 lines[start_idx:end_idx] = new_lines
 with open(filepath, 'w', encoding='utf-8', newline='') as f:
  f.writelines(lines)

def get_def(filepath: str, symbol_name: str) -> str:
 with open(filepath, 'r', encoding='utf-8') as f:
  content = f.read()
 tree = ast.parse(content)
 for node in ast.walk(tree):
  if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
   if node.name == symbol_name:
    start = node.lineno
    end = node.end_lineno
    if node.decorator_list:
     start = node.decorator_list[0].lineno
    slice_content = get_slice(filepath, start, end)
    return f"{start},{end}{chr(10)}{slice_content}"
 return "NOT_FOUND"

def set_def(filepath: str, symbol_name: str, new_content: str) -> None:
 res = get_def(filepath, symbol_name)
 if res == "NOT_FOUND":
  print(f"Error: Symbol '{symbol_name}' not found in {filepath}")
  sys.exit(1)
 lines_info = res.split(chr(10), 1)[0]
 start, end = lines_info.split(',')
 set_slice(filepath, start, end, new_content)
 print(f"Successfully updated '{symbol_name}' (lines {start}-{end}) in {filepath}")

if __name__ == "__main__":
 if len(sys.argv) < 2:
  print("Usage: python slice_tools.py <command> [args...]")
  sys.exit(1)
 cmd = sys.argv[1]
 if cmd == "get_slice":
  print(get_slice(sys.argv[2], sys.argv[3], sys.argv[4]), end="")
 elif cmd == "set_slice":
  with open(sys.argv[5], 'r', encoding='utf-8') as f:
   new_content = f.read()
  set_slice(sys.argv[2], sys.argv[3], sys.argv[4], new_content)
 elif cmd == "get_def":
  print(get_def(sys.argv[2], sys.argv[3]), end="")
 elif cmd == "set_def":
  with open(sys.argv[4], 'r', encoding='utf-8') as f:
   new_content = f.read()
  set_def(sys.argv[2], sys.argv[3], new_content)
