# frozen_string_literal: true

require "neeto-compliance"

require_relative "ui"
require_relative "../utils"

module Neetob
  class CLI::Base
    include Utils

    NEETO_APPS_LIST_LINK = "https://github.com/bigbinary/neeto-compliance/blob/main/data/neeto_repos.json#L2"

    attr_reader :ui

    def initialize
      @ui = CLI::UI.new
    end

    private

      def find_all_matching_apps_or_repos(apps, platform_name, sandbox_mode, quiet = false)
        all_neeto_repos = apps == ["all"]
        inform_about_current_working_mode(sandbox_mode, quiet)

        all_available_apps = sandbox_mode ?
          testing_apps(platform_name) :
          build_app_list_from_neeto_compliance(platform_name, all_neeto_repos)

        matching_apps = if apps == ["all"]
          all_available_apps
        elsif apps == ["engines"]
          all_engine_repos(sandbox_mode)
        elsif apps == ["nanos"]
          all_nano_repos(sandbox_mode)
        else
          match_apps(apps || ["*"], all_available_apps)
        end

        if matching_apps.length == 0
          error_msg = sandbox_mode ?
          "Only \"neeto-dummy\" app is available for sandbox mode. Remove the \"--sandbox\" flag to run the given command for all the neeto applications." :
          "No matching app is found in the neeto apps list maintained at \"#{NEETO_APPS_LIST_LINK}\""
          ui.error(error_msg)
          exit
        end

        matching_apps
      end

      def all_engine_repos(sandbox_mode)
        sandbox_mode ?
          testing_apps(:github) :
          NeetoCompliance::NeetoRepos.nanos_backend.map { |repo| "bigbinary/#{repo}" }
      end

      def all_nano_repos(sandbox_mode)
        sandbox_mode ?
          testing_apps(:github) :
          NeetoCompliance::NeetoRepos.nanos_mono_repos.map { |repo| "bigbinary/#{repo}" }
      end

      def match_apps(required_apps, available_apps)
        apps = required_apps&.map { |app| Regexp.new "#{app.gsub("*", "[-a-zA-Z0-9]*")}" }
        available_apps.select do |available_app|
          apps&.any? { |app| app.match?(available_app) }
        end
      end

      def read_json_file(path)
        file = File.read(path)
        JSON.parse(file)
      end

      def build_app_list_from_neeto_compliance(platform_name, all_neeto_repos)
        neeto_products = NeetoCompliance::NeetoRepos.products
        apps = all_neeto_repos ? fetch_all_neeto_repos : neeto_products.keys
        [:heroku, :neetodeploy].include?(platform_name) ? add_env_suffix(apps, neeto_products) : prefix_org_name(apps)
      end

      def add_env_suffix(apps, neeto_products)
        [
          suffix_slug(apps, :staging, neeto_products),
          suffix_slug(apps, :production, neeto_products)
        ].flatten.compact.sort
      end

      def suffix_slug(apps, suffix, neeto_products)
        apps.map { |app| neeto_products.dig(app, suffix.to_s) ? "#{app}-#{suffix}" : nil }
      end

      def prefix_org_name(apps)
        apps.map { |app| "bigbinary/#{app}" }
      end

      def testing_apps(platform_name)
        [:heroku, :neetodeploy].include?(platform_name) ? ["neeto-dummy"] : ["bigbinary/neeto-dummy"]
      end

      def inform_about_current_working_mode(sandbox_mode, quiet = false)
        return if quiet

        callout_message = "Running in the sandbox mode. \nOnly \"neeto-dummy\" app will be available."
        unless sandbox_mode
          callout_message = "Running in non-sandbox mode. \nAll neeto applications are available. Some of the actions are irreversible."
        end
        ui.say(callout_message)
      end

      def fetch_all_neeto_repos
        NeetoCompliance::NeetoRepos::products.keys +
        NeetoCompliance::NeetoRepos::nanos +
        NeetoCompliance::NeetoRepos::widgets +
        NeetoCompliance::NeetoRepos::chrome_extensions +
        NeetoCompliance::NeetoRepos::helper_packages +
        NeetoCompliance::NeetoRepos::electron_apps +
        NeetoCompliance::NeetoRepos::executables +
        NeetoCompliance::NeetoRepos::mobile_apps +
        NeetoCompliance::NeetoRepos::other_repos +
        NeetoCompliance::NeetoRepos::nanos_mono_repos
      end

      def find_all_matching_gems(gems = ["*"])
        all_available_gems = NeetoCompliance::NeetoRepos.nanos_mono_repos + NeetoCompliance::NeetoRepos.nanos_backend
        match_apps(gems || ["*"], all_available_gems)
      end

      def find_all_matching_frontend_packages(packages = ["*"])
        all_available_packages = NeetoCompliance::NeetoRepos.nanos_frontend
        match_apps(packages || ["*"], all_available_packages)
      end
  end
end