from django.urls import path
from django.utils.translation import gettext_lazy as _
from reviewboard.extensions.base import ExtensionManager
from reviewboard.site.urlresolvers import local_site_reverse
from django.http import JsonResponse
from django.shortcuts import render
from reviewboard.scmtools.models import Repository  # updated import
from djblets.extensions.hooks import TemplateHook
import os
import subprocess
import logging
logger = logging.getLogger("reviewboard.extensions.FileReview")
class FileReviewExtension(Extension):
  metadata = {
    'Name': 'FileReview',
    'Summary': _('Review complete files from a repository'),
    'Author': 'Roland',
    'Version': '0.1.0',
  }
  def initialize(self):
    logger.info("Initializing FileReviewExtension and registering URL patterns.")
    self.url_patterns = [
      path(
        'filereview/new/',
        self.create_file_review_request,
        name='filereview-new'
      ),
      path(
        'filereview/list-files/',
        self.list_repo_files,
        name='filereview-list-files'
      ),
    ]
    logger.debug("URL patterns registered: %s", self.url_patterns)
    # Inject a link into the main content area of the New Review Request page
    TemplateHook(
      self,
      "new-review-request-main",
      "filereview/navbar_link.html"
    )
  def create_file_review_request(self, request):
    logger.info("Accessed create_file_review_request view with method: %s", request.method)
    if request.method == 'POST':
      repo_id = request.POST.get('repository')
      file_paths = request.POST.getlist('files')
      logger.info("Received POST for repo_id=%s, files=%s", repo_id, file_paths)
      # ...logic to create a review request for selected files...
      return JsonResponse({'success': True, 'files': file_paths})
    else:
      repositories = Repository.objects.all()
      logger.info("Fetched %d repositories.", repositories.count())
      file_select_repos = [
        repo for repo in repositories
        if getattr(repo, 'tool', None) and getattr(repo.tool, 'name', '').lower() in ('git', 'subversion')
      ]
      logger.info("Filtered %d file-selectable repositories (Git/SVN).", len(file_select_repos))
      return render(request, 'filereview/new_review_request.html', {
        'repositories': repositories,
        'file_select_repos': file_select_repos,
      })
  def list_repo_files(self, request):
    repo_id = request.GET.get('repository')
    logger.info("Listing files for repository id: %s", repo_id)
    try:
      repo = Repository.objects.get(pk=repo_id)
    except Repository.DoesNotExist:
      logger.error("Repository with id %s does not exist.", repo_id)
      return JsonResponse({'files': [], 'error': 'Repository not found'}, status=404)
    files = []
    tool = getattr(repo, 'tool', None)
    tool_name = getattr(tool, 'name', '').lower() if tool else ''
    repo_path = repo.path
    username = getattr(repo, 'username', None)
    password = getattr(repo, 'password', None)
    logger.info("Repository type: %s, path: %s", tool_name, repo_path)
    if tool_name == 'git':
      try:
        logger.info("Attempting to list files from Git repository.")
        if username and password and repo_path.startswith('http'):
          from urllib.parse import urlparse, urlunparse
          parts = urlparse(repo_path)
          netloc = f"{username}:{password}@{parts.hostname}"
          if parts.port:
            netloc += f":{parts.port}"
          repo_url = urlunparse((parts.scheme, netloc, parts.path, parts.params, parts.query, parts.fragment))
        else:
          repo_url = repo_path
        ref_hash_output = subprocess.check_output(
          ['git', 'ls-remote', repo_url, 'refs/heads/master'],
          universal_newlines=True
        )
        ref_hash = ref_hash_output.split('\t')[0].strip()
        files_output = subprocess.check_output(
          ['git', 'ls-tree', '-r', '--name-only', ref_hash],
          universal_newlines=True
        )
        files = [f for f in files_output.strip().split('\n') if f]
        logger.info("Found %d files in Git repository.", len(files))
      except Exception as e:
        logger.error("Error listing files from Git: %s", e)
        files = []
    elif tool_name == 'subversion':
      try:
        logger.info("Attempting to list files from SVN repository.")
        svn_cmd = ['svn', 'list', '-R', repo_path]
        if username:
          svn_cmd.extend(['--username', username])
        if password:
          svn_cmd.extend(['--password', password])
        output = subprocess.check_output(
          svn_cmd,
          universal_newlines=True
        )
        files = [line.strip() for line in output.splitlines() if line and not line.endswith('/')]
        logger.info("Found %d files in SVN repository.", len(files))
      except Exception as e:
        logger.error("Error listing files from SVN: %s", e)
        files = []
    else:
      logger.warning("Repository type %s is not supported for file listing.", tool_name)
      files = []
    return JsonResponse({'files': files})