Capataz.config do
  disable ENV['CAPATAZ_DISABLE']

  maximum_iterations ENV['CAPATAZ_MAXIMUM_ITERATIONS'] || 3000

  deny_declarations_of :module, :class, :self, :def, :const, :ivar, :cvar, :gvar

  deny_invoke_of :require, :new, :create, :class, :eval, :class_eval, :instance_eval, :instance_variable_set, :instance_variable_get, :constants, :const_get, :const_set, :constantize

  allow_invoke_of :nil?, :present?, :is_a?, :respond_to?, :try, '==', '!='

  allowed_constants Psych, JSON, URI, File, Array, Hash, Nokogiri, Nokogiri::XML, Nokogiri::XML::Builder, Time, Base64, Digest, Digest::MD5, Digest::SHA256,
                    SecureRandom, Setup, Setup::Namespace, Setup::DataType, Setup::Schema, OpenSSL, OpenSSL::PKey, OpenSSL::PKey::RSA,
                    OpenSSL::Digest, OpenSSL::Digest::SHA1, OpenSSL::HMAC, OpenSSL::X509::Certificate, Setup::Webhook, Setup::Algorithm,
                    Setup::Task, Setup::Task::RUNNING_STATUS, Setup::Task::NOT_RUNNING_STATUS, Setup::Task::ACTIVE_STATUS, Setup::Task::NON_ACTIVE_STATUS,
                    Xmldsig, Xmldsig::SignedDocument, Zip, Zip::OutputStream, Zip::InputStream, StringIO, MIME::Mail, MIME::Text, MIME::Multipart::Mixed,
                    Spreadsheet, Spreadsheet::Workbook, Setup::Authorization, Setup::Connection, Devise, Cenit, JWT, Setup::XsltValidator, Setup::Translator,
                    Setup::Flow, WriteXLSX, MIME::DiscreteMediaFactory, MIME::DiscreteMedia, MIME::DiscreteMedia, MIME::Image, MIME::Application, DateTime,
                    Tenant, Setup::SystemNotification, Tempfile, MWS, MWS::Orders::Client, MWS::Feeds::Client,
                    Setup::Oauth2Authorization, Cenit::XMLRPC, CombinePDF, CSV, CGI


  # TODO Configure zip utility access when removing tangled access to Zip::[Output|Input]Stream
  # allow_on Zip, [:decode, :encode]
  #
  # allow_for Zip::Entry, [:name, :read]
  #

  allow_on CSV, [:parse, :generate]

  allow_on Setup::SystemNotification, :create_with

  allow_for Setup::CrossSharedCollection, [:pull, :shared?, :to_json, :share_json, :to_xml, :to_edi, :name]

  allow_on [Account, Tenant], [:find_where, :find_all, :switch, :notify, :data_type, :current]

  allow_for [Account, Tenant], [:id, :name, :key, :token, :notification_level, :switch, :get_owner, :owner, :errors]

  allow_on Cenit, [:homepage, :namespace, :slack_link, :fail]

  allow_on JWT, [:encode, :decode]

  allow_on Devise, [:friendly_token]

  allow_on Spreadsheet::Workbook, [:new_workbook]

  allow_on MIME::Multipart::Mixed, [:new_message]

  allow_on MIME::Mail, [:new_message]

  allow_on MIME::Text, [:new_text]

  allow_on JSON, [:parse, :generate, :pretty_generate]

  allow_on Psych, [:load, :add_domain_type]

  allow_on YAML, [:load, :add_domain_type]

  allow_on URI, [:decode, :encode, :encode_www_form, :parse]

  allow_on CGI, [:escape, :unescape]

  allow_on StringIO, [:new_io]

  allow_on File, [:dirname, :basename]

  allow_on Time, [:strftime, :at, :year, :month, :day, :mday, :wday, :hour, :min, :sec, :now, :to_i, :utc, :getlocal, :gm, :gmtime, :local]

  allow_on DateTime, [:parse, :strftime, :strptime, :now]

  allow_on Xmldsig::SignedDocument, [:new_document, :sign]

  allow_on OpenSSL::PKey::RSA, [:new_rsa]

  allow_on OpenSSL::X509::Certificate, [:new_certificate]

  allow_on OpenSSL::Digest::SHA1, [:digest, :new_sha1]

  allow_for ActionView::Base, [
    # Form and form fields helpers
    :text_field, :password_field, :hidden_field, :file_field, :color_field, :search_field, :telephone_field,
    :phone_field, :date_field, :time_field, :datetime_field, :datetime_local_field, :month_field, :week_field,
    :url_field, :email_field, :number_field, :range_field,

    :text_field_tag, :hidden_field_tag, :file_field_tag, :password_field_tag, :color_field_tag, :search_field_tag,
    :telephone_field_tag, :phone_field_tag, :date_field_tag, :time_field_tag, :datetime_field_tag,
    :datetime_local_field_tag, :month_field_tag, :week_field_tag, :url_field_tag, :email_field_tag, :number_field_tag,
    :range_field_tag, :select_tag, :check_box_tag, :radio_button_tag, :submit_tag, :button_tag, :image_submit_tag,
    :form_tag, :text_area_tag, :utf8_enforcer_tag, :options_for_select,

    # Other html tags helpers
    :javascript_tag, :label_tag, :field_set_tag, :auto_discovery_link_tag, :favicon_link_tag, :image_tag, :video_tag,
    :audio_tag, :content_tag, :time_tag, :csrf_meta_tag,

    # Asset urls helpers
    :asset_url, :javascript_url, :stylesheet_url, :image_url, :video_url, :audio_url, :font_url,

    # Link tags helpers
    :stylesheet_link_tag, :link_to_previous_page, :link_to_next_page, :strip_links, :link_to, :link_to_if,
    :favicon_link_tag,

    # App control helpers
    :application, :namespace, :application_title, :url_for, :app_url, :render_template, :data_type, :data_file, :resource,
    :connection, :current_user, :current_account, :sign_in_url, :sign_out_url, :can?, :cannot?, :action, :flash_alert_class,
    :xhr?,

    # Other helpers
    :escape_javascript, :j, :content_for, :content_for?, :flash
  ]

  allow_on Setup::Task, [:current, :break, :where, :all]

  allow_on Setup::Task::RUNNING_STATUS, [:include?]

  allow_on Setup::Task::NOT_RUNNING_STATUS, [:include?]

  allow_on Setup::Task::ACTIVE_STATUS, [:include?]

  allow_on Setup::Task::NON_ACTIVE_STATUS, [:include?]

  allow_on Nokogiri::XML::Builder, [:with, :new_builder, :[]]

  allow_on Nokogiri::XML, [:search]

  allow_on Setup::Connection, Setup::Webhook.method_enum + [:webhook_for, :where, :del] - [:delete]

  allow_on Setup::Webhook, [:where]

  allow_on Setup::Translator, [:run, :where]

  allow_on WriteXLSX, [:new_xlsx]

  allow_on MIME::DiscreteMedia, [:create_media]

  allow_on MIME::Application, [:new_app]

  allow_on MIME::Image, [:new_img]

  allow_on MIME::DiscreteMedia, [:new_media]

  allow_on MIME::DiscreteMediaFactory, [:create_factory]

  allow_on MWS::Feeds::Client, [:new_feed]

  allow_on Magick::Image, [:read]

  allow_on Hash, Hash.methods

  allow_for [Mongoff::Model], [:where, :all, :data_type]

  # allow_for [Setup::Raml],  [:id, :name, :slug, :to_json, :to_edi, :to_hash, :to_xml, :to_params, :records_model, :ref_hash, :raml_parse, :build_hash, :map_collection]

  allow_for [Class],
            [
              :where, :all, :now,
              :new_sign, :digest, :new_sha1, :hexdigest, :new_rsa, :sign, :new_certificate,
              :data_type, :id,
              :write_buffer, :put_next_entry, :write,
              :encode64, :decode64, :urlsafe_encode64, :new_io, :get_input_stream, :open, :new_document
            ] + Setup::Webhook.method_enum + [:del] - [:delete]

  allow_for [Mongoid::Criteria, Mongoff::Criteria], Enumerable.instance_methods(false) + Mongoid::Criteria::Queryable.instance_methods(false) + [:each, :blank?, :limit, :skip, :where, :distinct]

  allow_for Setup::Task, [:status, :scheduler, :schedule, :state, :resume_in, :run_again, :progress, :progress=, :update, :destroy, :notifications, :notify, :to_json, :share_json, :to_edi, :to_hash, :to_xml, :id, :current_execution, :sources, :description, :agent, :join]

  allow_for Setup::Scheduler, [:activate, :activated?, :deactivate, :name, :to_json, :share_json, :to_edi, :to_hash, :to_xml, :namespace]

  allow_for Setup::Webhook::HttpResponse, [:code, :body, :headers, :content_type]

  allow_for Setup::Webhook::Response, [:code, :body, :headers, :content_type]

  allow_for Setup::DataType, ((%w(_json _xml _edi) + ['']).collect do |format|
    %w(create new create!).collect do |action|
      if action.end_with?('!')
        "#{action.chop}_from#{format}!"
      else
        "#{action}_from#{format}"
      end
    end + [:create_from]
  end + [:name, :slug, :to_json, :share_json, :to_edi, :to_hash, :to_xml, :to_params, :records_model, :namespace, :id, :ns_slug, :title, :where, :all, :build_indices] + Setup::DataType::RECORDS_MODEL_METHODS).flatten

  deny_for [Setup::DynamicRecord, Mongoff::Record], ->(instance, method) do
    return false if [:id, :to_json, :share_json, :to_edi, :to_hash, :to_xml, :to_xml_element, :to_params, :from_json, :from_xml, :from_edi, :[], :[]=, :save, :save!, :all, :where, :orm_model, :==, :errors, :destroy, :new_record?].include?(method)
    return false if instance.orm_model.data_type.records_methods.any? { |alg| alg.name == method.to_s }
    return false if [:data].include?(method) && instance.is_a?(Mongoff::GridFs::FileFormatter)
    if (method = method.to_s).end_with?('=')
      method = method.chop
    end
    instance.orm_model.property_schema(method).nil?
  end

  deny_for Cenit::Control, [:model_adapter, :controller, :view]

  allow_for User, [:id, :short_name, :name, :given_name, :family_name, :picture_url, :number, :email, :sign_in_count, :created_at, :updated_at, :current_sign_in_ip, :last_sign_in_ip, :has_role?, :account, :accounts]

  allow_on User, [:find_where, :find_all, :current]

  allow_on CombinePDF, [:new_pdf]
end
