#!/usr/bin/env ruby

require "bundler"
require "bundler/setup"

require "manageiq-cross_repo"
require "optimist"

opts = Optimist.options do
  usage "--test-repo repo [--repos repo1 repo2 ...]"

  version "v#{ManageIQ::CrossRepo::VERSION}\n"

  synopsis <<~EOS.chomp

    manageiq-cross_repo is a cross repository test framework for the ManageIQ project.
    Its purpose is to allow running multiple repository tests suites in the context
    of other repositories and is particularly useful when trying to determine if the
    changes you are making as a developer will affect the other test suites.
  EOS

  opt :test_repo, <<~EOS, :type => :string, :default => ENV["TEST_REPO"].presence || "ManageIQ/manageiq@master"
    This is the repository which will be tested.
    Can also be passed as a TEST_REPO environment variable.
  EOS

  opt :repos, <<~EOS, :type => :strings, :default => Array(ENV["REPOS"].presence)
    Optional, a list of other repos and/or gems to override while running the tests.
    If any of the repositories in the list are a core repository that will
    be used as the root repository, otherwise ManageIQ/manageiq@master will be the default.
    Can also be passed as a REPOS environment variable.
  EOS

  opt :test_suite, <<~EOS, :type => :string, :default => ENV["TEST_SUITE"].presence
    Optional, the name of a rake test suite to pass as an environment variable to the test being run.
    This is commonly used by the CI config to conditionally perform different setup tasks
    and also to run different test suites, e.g. spec:javascript.
  EOS

  opt :script_cmd, <<~EOS, :type => :string, :default => ENV["SCRIPT_CMD"].presence
    Optional, a command string for running the specs.
    If present this will override the the script section of the test_repo's CI config
  EOS


  # Manually add these so they appear in the right order in the help output
  banner ""
  opt :version, "Print version and exit"
  opt :help,    "Show this message"

  banner <<~EOS.chomp

    Repo Formats:
      Remote: [org/]repository[@ref|#pr]
        org:        Optional, defaults to ManageIQ.
        repository: Required, the name of the repository.
        @ref:       Optional, defaults to master if #pr not set. Can be a branch, tag, or SHA. Mutually exclusive with #pr.
        #pr:        Optional, references a pull-request number. Mutually exclusive with @ref.

      URL: https://github.com/org/repository, https://github.com/org/repository/tree/branch,
           https://github.com/org/repository/commit/sha, https://github.com/org/repository/pull/pr

      Local: Either a fully qualified path or a relative path (e.g. /path/to/repo, ~/relative/to/home, ../relative/to/current/dir)
  EOS

  banner <<~EOS.chomp

    Examples:
      # Test a plugin against ManageIQ master
      manageiq-cross_repo --test-repo manageiq-ui-classic

      # Test a plugin against a ManageIQ SHA
      manageiq-cross_repo --test-repo manageiq-ui-classic --repos manageiq@1234abcd

      # Test a plugin branch
      manageiq-cross_repo --test-repo manageiq-ui-classic@feature

      # Test a plugin branch from a fork
      manageiq-cross_repo --test-repo johndoe/manageiq-ui-classic@feature

      # Test a plugin PR
      manageiq-cross_repo --test-repo manageiq-ui-classic#1234

      # Test a plugin with a set of other plugins
      manageiq-cross_repo --test-repo manageiq-ui-classic --repos manageiq-providers-vmware@feature manageiq-content@feature

      # Test a plugin branch with a ManageIQ SHA and a set of other plugins
      manageiq-cross_repo --test-repo manageiq-ui-classic@feature --repos manageiq@1234abcd manageiq-providers-vmware@feature manageiq-content@feature

      # Run core tests with ManageIQ master using a gem version
      manageiq-cross_repo --repos johndoe/manageiq-ui-classic@feature

      # Run core tests for a branch and a set of gems
      manageiq-cross_repo --test-repo johndoe/manageiq@feature --repos manageiq-providers-vmware@feature manageiq-content@feature
  EOS
end

opts[:repos] = opts[:repos].flatten.flat_map { |repo| repo.split(",").map(&:strip) }
test_repo, repos, test_suite, script_cmd = opts.values_at(:test_repo, :repos, :test_suite, :script_cmd)

begin
  ManageIQ::CrossRepo.run(
    :test_repo  => test_repo,
    :repos      => repos,
    :test_suite => test_suite,
    :script_cmd => script_cmd
  )
rescue ArgumentError => e
  Optimist.die e
end