class ApiController < ApplicationController

  def log
    @log || Logging.logger[ApiController]
  end

  @@html_encoder = HTMLEntities.new

  # define common error handlers
  rescue_from 'JamRuby::StateError' do |exception|
    @exception = exception
    render "errors/state_error", :status => 400
  end
  rescue_from 'JamRuby::JamArgumentError' do |exception|
    @exception = exception
    render "errors/jam_argument_error", :status => 422
  end
  rescue_from 'JamRuby::JamPermissionError' do |exception|
    @exception = exception
    render "errors/permission_error", :status => 403
  end
  rescue_from 'JamRuby::JamRecordNotFound' do |exception|
    @exception = exception
    render "errors/record_not_found", :status => 404
  end
  rescue_from 'JamRuby::ConflictError' do |exception|
    @exception = exception
    render "errors/conflict_error", :status => 409
  end
  rescue_from 'Stripe::StripeError' do |exception|
    @exception = exception
    render "errors/stripe_error", :status => 422
  end
  rescue_from 'ActiveRecord::RecordNotFound' do |exception|
    log.debug(exception)
    render :json => { :errors => { :resource => ["record not found"] } }, :status => 404
  end
  rescue_from 'PG::Error' do |exception|
    log.debug(exception)
    if exception.to_s.include? "duplicate key value violates unique constraint"
      render :json => { :errors => { :resource => ["resource already exists"] } }, :status => 409 # 409 = conflict
    else
      raise exception
    end
  end


  protected

    def recursive_errors(model, children)
      response = {errors:model.errors, _children:{}}
      children_response = response[:_children]
      children.each do |child|
        child_response = []
        associations = model.send(child)
        if associations
          associations.each do |association|
            child_response << {errors: association.errors}
          end
        end
        children_response[child] = child_response
      end

      render json: response, status: :unprocessable_entity, layout:nil

    end

    def respond_with_model(model, options = {})
      if model.errors.any?
        respond_with model, status: :unprocessable_entity, layout: nil
      else
        status = options[:new] && options[:new] == true ? 201 : 200
        redirect_on_success = options[:location]
        if redirect_on_success
          location = redirect_on_success.call
          raise "location must return something" unless location # development time error
          respond_with model, responder: ApiResponder, status: status, location: location, layout: nil
        else
          respond_with model, responder: ApiResponder, status: status, location:nil
        end
      end
    end


    def auth_user
      unless current_user.id == params[:id]
        raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
      end
      
      @user = User.find(params[:id])
    end

  def guard_school_same_scope(user, target)
    if !user || !target
      return true
    end
    if !user.is_platform_instructor && !target.is_platform_instructor
      return user.school_id == target.school_id
    else
      return true
    end

  end

    def optional_auth_user
      if current_user.nil?
        @user = nil
      else
        auth_user
      end
    end

    def affiliate_partner
      if params[:affiliate_id]
        @partner = AffiliatePartner.find(params[:affiliate_id])
        if @partner.nil?
          raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
        elsif @partner.partner_user.nil?
          raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
        elsif !current_user.admin || @partner.partner_user != current_user
          raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
        end
      elsif current_user
        @partner = current_user.affiliate_partner
      else
        raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
      end
    end
end
