<commit_before>require 'thor'
require 'yaml'
YAML::ENGINE.yamler = 'syck' if defined? Syck
require 'abbrev'
require 'base64'
require 'fileutils'
require 'json'
require 'filewatcher'
require 'launchy'
require 'mimemagic'

MimeMagic.add('application/json', extensions: %w(json js), parents: 'text/plain')
MimeMagic.add('application/x-pointplus', extensions: %w(scss styl), parents: 'text/css')
MimeMagic.add('application/font-woff2', extensions: %w(woff2), parents: 'font/opentype')
MimeMagic.add('application/vnd.ms-fontobject', extensions: %w(eot), parents: 'font/opentype')

module OpencodeTheme
  class Cli < Thor
    include Thor::Actions

    IGNORE = %w(config.yml)
    DEFAULT_WHITELIST = %w(configs/ css/ elements/ img/ layouts/ pages/ js/)
    TIMEFORMAT = '%H:%M:%S'

    tasks.keys.abbrev.each do |shortcut, command|
      map shortcut => command.to_sym
    end

    map 'new' => :bootstrap
    map 'rm' => :remove

    desc 'configure API_KEY PASSWORD THEME_ID', 'Configura o tema que sera modificado'
    def configure(api_key = nil, password = nil, theme_id = nil)
      config = { api_key: api_key, password: password, theme_id: theme_id }

      if api_key.nil? || password.nil? || theme_id.nil?
        response = {}
        response["message"] = 'necessário informar api_key e password e theme_id.'
        return report_error(Time.now, 'Configuration [FAIL]', response)
      end
      OpencodeTheme.config = config

      response = OpencodeTheme.check_config
      if response[:success]
        config.merge!(preview_url: response[:response]['preview'])
        create_file('config.yml', config.to_yaml, force: true)
        say('Configuration [OK]', :green)
      else
        report_error(Time.now, 'Configuration [FAIL]', response[:response])
      end
    end

    desc 'list', 'Lista todos os temas da loja'
    def list
      config = OpencodeTheme.config
      response = OpencodeTheme.list
    if response[:response]["authentication"] == false
      response = {}
      response["message"] = 'necessário autenticação'
      return report_error(Time.now, 'Configuration [FAIL]', response)
    end

      if response[:success]
        say("\n")
        response[:response]['themes'].each do |theme|
          color = theme['published'] == '1' ? :green : :red
          say('Theme name:   ', color)
          say("#{theme['name']}\n", color)
          say('Theme ID:     ', color)
          say("#{theme['id']}\n", color)
          say('Theme status: ', color)
          say("#{(theme['published'])}\n\n", color)
        end
      else
        report_error(Time.now, 'Could not list now', response[:response])
      end
    end

    desc 'clean', 'Limpa o cache de arquivos estáticos'

    def clean
      config = OpencodeTheme.config
      response = OpencodeTheme.clean
      if response[:success]
        say('Clean cache [OK]\n', :green)
      else
        report_error(Time.now, 'Clean cache [FAIL]', response[:response])
      end
    end

    desc 'new API_KEY PASSWORD THEME_NAME THEME_BASE', 'Cria um novo tema com o nome informado'
    method_option :master, type: :boolean, default: false
    def bootstrap(api_key = nil, password = <PASSWORD>, theme_name = 'default', theme_base = 'default')
      OpencodeTheme.config = { api_key: api_key, password: password }
      check_config = OpencodeTheme.check_config

      if check_config[:success]
        say('Configuration [OK]', :green)
      else
        report_error(Time.now, 'Configuration [FAIL]', check_config[:response])
        return
      end

      response = OpencodeTheme.theme_new(theme_base, theme_name)

      if response[:success]
        say("Create #{theme_name} theme on store", :green)
      else
        report_error(Time.now, 'Could not create a new theme', response[:response])
        return
      end

      say("Creating directory named #{theme_name}", :green)
      empty_directory(theme_name)

      say("Saving configuration to #{theme_name}", :green)
      OpencodeTheme.config.merge!(theme_id: response[:response]['theme_id'], preview_url: response[:response]['preview'])
      create_file("#{theme_name}/config.yml", OpencodeTheme.config.to_yaml)

      say("Downloading #{theme_name} assets from Opencode")
      Dir.chdir(theme_name)
      download
    end

    desc 'open', 'Abre a loja no navegador'
    def open(*keys)
      if Launchy.open opencode_theme_url
        say('Done.', :green)
      end
    end

    desc 'download FILE', 'Baixa o arquivo informado ou todos se FILE for omitido'
    method_option :quiet, type: :boolean, default: false
    method_option :exclude
    def download(*keys)
      assets = keys.empty? ? OpencodeTheme.asset_list : keys
      if assets.is_a? String
        return report_error(Time.now, "List Could not download", JSON.parse(assets))
      end
      if options['exclude']
        assets = assets.delete_if { |asset| asset =~ Regexp.new(options['exclude']) }
      end
      assets.each do |asset|
        asset = URI.decode(asset)
        begin
          download = download_asset(asset)
          if download
            say("#{OpencodeTheme.api_usage} Downloaded: #{asset}", :green) unless options['quiet'] || !download
            say('Done.', :green) unless options['quiet']
          end
        rescue
          say("Error: #{asset}", :red)
        end
      end
    end

    desc 'upload FILE', 'Sobe o arquivo informado ou todos se FILE for omitido'
    method_option :quiet, type: :boolean, default: false
    def upload(*keys)
      assets = keys.empty? ? local_assets_list : keys
      assets.each do |asset|
        send_asset("#{asset}", options['quiet'])
      end
      say('Done.', :green) unless options['quiet']
    end

    desc 'rm FILE', 'Remove um arquivo do tema (apenas se o tema nao estiver publicado)'
    method_option :quiet, type: :boolean, default: false
    def remove(*keys)
      keys.each do |key|<commit_msg>condiciona a impressão da mensagem à opção `quiet`<commit_after>require 'thor'
require 'yaml'
YAML::ENGINE.yamler = 'syck' if defined? Syck
require 'abbrev'
require 'base64'
require 'fileutils'
require 'json'
require 'filewatcher'
require 'launchy'
require 'mimemagic'

MimeMagic.add('application/json', extensions: %w(json js), parents: 'text/plain')
MimeMagic.add('application/x-pointplus', extensions: %w(scss styl), parents: 'text/css')
MimeMagic.add('application/font-woff2', extensions: %w(woff2), parents: 'font/opentype')
MimeMagic.add('application/vnd.ms-fontobject', extensions: %w(eot), parents: 'font/opentype')

module OpencodeTheme
  class Cli < Thor
    include Thor::Actions

    IGNORE = %w(config.yml)
    DEFAULT_WHITELIST = %w(configs/ css/ elements/ img/ layouts/ pages/ js/)
    TIMEFORMAT = '%H:%M:%S'

    tasks.keys.abbrev.each do |shortcut, command|
      map shortcut => command.to_sym
    end

    map 'new' => :bootstrap
    map 'rm' => :remove

    desc 'configure API_KEY PASSWORD THEME_ID', 'Configura o tema que sera modificado'
    def configure(api_key = nil, password = <PASSWORD>, theme_id = nil)
      config = { api_key: api_key, password: password, theme_id: theme_id }

      if api_key.nil? || password.nil? || theme_id.nil?
        response = {}
        response["message"] = 'necessário informar api_key e password e theme_id.'
        return report_error(Time.now, 'Configuration [FAIL]', response)
      end
      OpencodeTheme.config = config

      response = OpencodeTheme.check_config
      if response[:success]
        config.merge!(preview_url: response[:response]['preview'])
        create_file('config.yml', config.to_yaml, force: true)
        say('Configuration [OK]', :green)
      else
        report_error(Time.now, 'Configuration [FAIL]', response[:response])
      end
    end

    desc 'list', 'Lista todos os temas da loja'
    def list
      config = OpencodeTheme.config
      response = OpencodeTheme.list
    if response[:response]["authentication"] == false
      response = {}
      response["message"] = 'necessário autenticação'
      return report_error(Time.now, 'Configuration [FAIL]', response)
    end

      if response[:success]
        say("\n")
        response[:response]['themes'].each do |theme|
          color = theme['published'] == '1' ? :green : :red
          say('Theme name:   ', color)
          say("#{theme['name']}\n", color)
          say('Theme ID:     ', color)
          say("#{theme['id']}\n", color)
          say('Theme status: ', color)
          say("#{(theme['published'])}\n\n", color)
        end
      else
        report_error(Time.now, 'Could not list now', response[:response])
      end
    end

    desc 'clean', 'Limpa o cache de arquivos estáticos'

    def clean
      config = OpencodeTheme.config
      response = OpencodeTheme.clean
      if response[:success]
        say('Clean cache [OK]\n', :green)
      else
        report_error(Time.now, 'Clean cache [FAIL]', response[:response])
      end
    end

    desc 'new API_KEY PASSWORD THEME_NAME THEME_BASE', 'Cria um novo tema com o nome informado'
    method_option :master, type: :boolean, default: false
    def bootstrap(api_key = nil, password = <PASSWORD>, theme_name = 'default', theme_base = 'default')
      OpencodeTheme.config = { api_key: api_key, password: password }
      check_config = OpencodeTheme.check_config

      if check_config[:success]
        say('Configuration [OK]', :green)
      else
        report_error(Time.now, 'Configuration [FAIL]', check_config[:response])
        return
      end

      response = OpencodeTheme.theme_new(theme_base, theme_name)

      if response[:success]
        say("Create #{theme_name} theme on store", :green)
      else
        report_error(Time.now, 'Could not create a new theme', response[:response])
        return
      end

      say("Creating directory named #{theme_name}", :green)
      empty_directory(theme_name)

      say("Saving configuration to #{theme_name}", :green)
      OpencodeTheme.config.merge!(theme_id: response[:response]['theme_id'], preview_url: response[:response]['preview'])
      create_file("#{theme_name}/config.yml", OpencodeTheme.config.to_yaml)

      say("Downloading #{theme_name} assets from Opencode")
      Dir.chdir(theme_name)
      download
    end

    desc 'open', 'Abre a loja no navegador'
    def open(*keys)
      if Launchy.open opencode_theme_url
        say('Done.', :green)
      end
    end

    desc 'download FILE', 'Baixa o arquivo informado ou todos se FILE for omitido'
    method_option :quiet, type: :boolean, default: false
    method_option :exclude
    def download(*keys)
      assets = keys.empty? ? OpencodeTheme.asset_list : keys
      if assets.is_a? String
        return report_error(Time.now, "List Could not download", JSON.parse(assets))
      end
      if options['exclude']
        assets = assets.delete_if { |asset| asset =~ Regexp.new(options['exclude']) }
      end
      assets.each do |asset|
        asset = URI.decode(asset)
        begin
          download = download_asset(asset)
          if download
            say("#{OpencodeTheme.api_usage} Downloaded: #{asset}", :green) unless options['quiet'] || !download
            say('Done.', :green) unless options['quiet']
          end
        rescue
          say("Error: #{asset}", :red) unless options['quiet']
        end
      end
    end

    desc 'upload FILE', 'Sobe o arquivo informado ou todos se FILE for omitido'
    method_option :quiet, type: :boolean, default: false
    def upload(*keys)
      assets = keys.empty? ? local_assets_list : keys
      assets.each do |asset|
        send_asset("#{asset}", options['quiet'])
      end
      say('Done.', :green) unless options['quiet']
    end

    desc 'rm FILE', 'Remove um arquivo do tema (apenas se o tema nao estiver publicado)'
    method_option :quiet, type: :boolean, default: false
    def remove(*keys)
      keys.each do |key|
{'fraction_non_alphanumeric': 0.12590472984346068, 'fraction_numerical': 0.000841609156707625, 'mean_word_length': 3.0172413793103448, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 21, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5363463', 'n_tokens_mistral': 3644, 'n_tokens_neox': 3524, 'n_words': 974}