#!/usr/bin/env ruby
require 'gli'
require 'dropsonde'

class Dropsonde
  extend GLI::App

  @cache = nil
  @puppetdb_session = Dropsonde.new

  program_desc 'A simple telemetry tool for Puppet infrastructures'
  config_file  "#{File.dirname(Puppet.settings[:confdir])}/telemetry.yaml"
  version      Dropsonde::VERSION

  desc 'Verbose logging'
  switch [:verbose, :v]

  desc 'Auto update the Forge module name cache if expired'
  switch [:update], :default_value => true

  desc 'Path to cache directory'
  flag [:cachepath], :default_value => "#{Puppet.settings[:vardir]}/dropsonde"

  desc 'Forge module cache ttl in days'
  flag [:ttl], :default_value => 7, :type => Integer

  desc 'List of metrics to omit'
  flag [:disable, :d], :type => Array

  desc 'Only load these metrics'
  flag [:enable, :e], :type => Array

  desc 'Any number or string used to generate the randomized site ID.'
  flag [:seed]

  desc 'Static site ID'
  flag [:siteid]

  pre do |global, command, options, args|
    Dropsonde.settings = global
    @cache = Dropsonde::Cache.new(global[:cachepath], global[:ttl], global[:update])
  end

  desc 'Manually update the Forge module name cache'
  command :update do |c|
    c.action do |global, options, args|
      @cache.update
    end
  end

  desc 'List all available metrics'
  command :list do |c|
    c.action do |global, options, args|
      Dropsonde.list_metrics
    end
  end

  desc 'Preview the telemetry report that will be submitted'
  command :preview do |c|
    c.desc 'The output format to use'
    c.flag [:format], :default_value => 'human'

    c.action do |global, options, args|
      @cache.autoupdate
      Dropsonde.generate_report(options[:format], @puppetdb_session)
    end
  end

  desc 'Submit a telemetry report'
  command :submit do |c|
    c.desc 'Telemetry endpoint'
    c.flag [:endpoint], :default_value => 'https://prod.dujour.k8s.puppet.net'

    c.desc 'Telemetry port'
    c.flag [:port], :default_value => 443, :type => Integer

    c.action do |global, options, args|
      @cache.autoupdate
      Dropsonde.submit_report(options[:endpoint], options[:port])
    end
  end

  desc "Commands useful for developers"
  command :dev do |t|
    t.desc 'Open a Pry shell for debugging'
    t.command :shell do |c|
      c.action do |global, options, args|
        require 'pry'
        binding.pry
      end
    end

    t.desc 'Generate a complete schema for all metrics'
    t.long_desc "This generates the schema that is used to create or update the BigQuery
                 database. Every report is also validated against this schema before
                 submission, so you can be assured that this is a complete representation
                 of what data is collected and run through aggregation filters."
    t.command :schema do |c|
      c.action do |global, options, args|
        Dropsonde.generate_schema
      end
    end

    t.desc 'Generate an example of random data to simulate actual reports'
    t.long_desc "The submitted telemetry reports are treated as sensitive material. Very
                few people have access to that raw data. Instead, it's run through some
                data aggregation filters to generate the published statistics we share.
                Writing those aggregation queries is difficult without data to work with,
                so this command generates a representative example of random data.

                This is in jsonl format for direct upload to BigQuery."
    t.command :example do |c|
      c.desc 'How many rows to generate'
      c.flag [:size], :default_value => 100, :type => Integer

      c.desc 'Filename for the output (in jsonl format).'
      c.flag [:filename], :default_value => 'example.jsonl'

      c.action do |global, options, args|
        @cache.autoupdate
        Dropsonde.generate_example(options[:size], options[:filename])
      end
    end
  end

end

exit Dropsonde.run(ARGV)
