# frozen_string_literal: true

require_relative "../base"

module Neetob
  class CLI
    module Github
      module MakePr
        class Base < Github::Base
          BRANCH_NAME = "neeto_compliance"
          PR_TITLE = "Neeto Compliance"
          attr_accessor :branch_name, :pr_title

          def initialize(pr_title = PR_TITLE, branch_name = BRANCH_NAME)
            super()
            @branch_name = branch_name || BRANCH_NAME
            @pr_title = pr_title || PR_TITLE
          end

          private

            def bundle_install!(repo, local_repo = false)
              execute_command!("#{cd_to_repo(repo, local_repo)} & rbenv local 3.3.5 & bundle install")
            end

            def yarn_install!(repo, local_repo = false)
              execute_command!("#{cd_to_repo(repo, local_repo)} & yarn install")
            end

            def delete_and_create_temp_neetob_dir
              `rm -rf /tmp/neetob`
              `mkdir /tmp/neetob`
            end

            def repo_name_without_org_suffix(repo)
              repo.split("/").last
            end

            def shallow_clone_repo_in_tmp_dir!(repo)
              execute_command!(
                "git clone --quiet --depth 1 git@github.com:#{repo}.git /tmp/neetob/#{repo_name_without_org_suffix(repo)}"
              )
            end

            def clone_repo_in_tmp_dir(repo)
              `git clone --quiet git@github.com:#{repo}.git /tmp/neetob/#{repo_name_without_org_suffix(repo)}`
            end

            def add_commmit_and_push_changes!(repo, local_repo = false)
              create_commit!(repo, local_repo)
              push_changes!(repo, local_repo)
            end

            def create_commit!(repo, local_repo)
              execute_command!("#{cd_to_repo(repo, local_repo)} && git add . && git commit -m \"#{pr_title}\"")
            end

            def push_changes!(repo, local_repo)
              execute_command!("#{cd_to_repo(repo, local_repo)} && git push -u origin #{branch_name} --force")
            end

            def delete_local_feature_branch(repo, local_repo = false)
              `#{cd_to_repo(repo, local_repo)} && git checkout main && git branch -D #{branch_name}`
            end

            def checkout_to_new_branch(repo, local_repo)
              `#{cd_to_repo(repo, local_repo)} && git checkout -b #{branch_name}`
            end

            def checkout_to_feature_branch(repo, local_repo)
              `#{cd_to_repo(repo, local_repo)} && git checkout #{branch_name}`
            end

            def delete_remote_feature_branch(repo, local_repo)
              `#{cd_to_repo(repo, local_repo)} && git push origin --delete #{branch_name}`
            end

            def check_and_delete_remote_branch(repo, local_repo = false)
              checkout_to_feature_branch(repo, local_repo)
              if $?.success?
                ui.info("Remote branch found with the name \"#{branch_name}\"")
                delete_remote_feature_branch(repo, local_repo)
                delete_local_feature_branch(repo, local_repo)
              end
              checkout_to_new_branch(repo, local_repo)
            end

            def cd_to_repo(repo, local = false)
              local ? "cd ./#{repo_name_without_org_suffix(repo)}" : "cd /tmp/neetob/#{repo_name_without_org_suffix(repo)}"
            end

            def add_org_suffix(repos)
              repos.map { |repo| "bigbinary/#{repo}" }
            end

            def build_matching_repos_list(should_fix_nanos, should_fix_frontend_packages = false)
              return add_org_suffix(find_all_matching_gems) if should_fix_nanos

              return add_org_suffix(find_all_matching_frontend_packages) if should_fix_frontend_packages

              find_all_matching_apps_or_repos(repos, :github, sandbox)
            end

            def stash_local_changes(repo, local_repo)
              `#{cd_to_repo(repo, local_repo)} && git stash && git checkout main && git pull origin main`
            end

            def warn_about_local_repos
              ui.say("The above mentioned command will be using the local repos. Local changes will be lost!\n")
            end

            def execute_command!(command)
              `#{command}`
              raise Neetob::CommandExecutionError.new(command, $?.exitstatus) unless $?.success?
            end
        end
      end
    end
  end
end