require 'authentication_methods'
require 'digest/sha1'
require 'securerandom'
require 'pixways'
require 'pixways/searches_helper'

class ApplicationController < ActionController::Base

  rescue_from CanCan::AccessDenied do |exception|
    exception.default_message = I18n.t('flash.alert_cancan')
    flash[:alert] = exception.message
    redirect_to '/home'
  end

  helper :all
  include AuthenticationMethods
  include Pixways

  helper_method :current_user_session, :current_user

  before_filter :login_required
  before_filter :set_locale
  before_filter :set_time_zone
  before_filter :prepend_view_path_if_mobile

  def api_call(demand, login, var_id, parameters)
    unless Server.itself? PIXADMIN_SERVER_NAME
      server_url = "http://#{Server.find_by_name("Pixadmin").host}:#{Server.find_by_name("Pixadmin").api_port}/"
      cs_name = Server.find_by_is_self(true).name
      api_res = ""
      url_key = "cs_request"
      safeurl = URI.encode("#{server_url}#{url_key}".strip)
      if !parameters[:file_path].blank? && File.exists?(parameters[:file_path])
        payload = {
          "cs_demand" => demand, "cs_name" => cs_name, "user_login" => login, "var_id" => var_id, "parameters" => parameters,
          attached_file: File.new(parameters[:file_path], 'rb')
        }
        content_type = "multipart/mixed"
      else
        payload = { "cs_demand" => demand, "cs_name" => cs_name, "user_login" => login, "var_id" => var_id, "parameters" => parameters }
        content_type = :json
      end

      begin
        res = RestClient::Request.execute(
          method: :post,
          url: safeurl,
          open_timeout: 5,
          read_timeout: 5,
          ssl_timeout: 5,
          timeout: 5,
          payload: payload,
          content_type: :json,
          accept: content_type
        )
      rescue => e
        logger.info"**** rescue #{e.inspect}"
        api_res = "Erreur Rest : #{e.inspect}"
      end
      if api_res.blank?
        if Pixways.valid_json(res.body)
          retour = JSON.parse(res.body)
          api_res = retour["result"]
        end
      else
        newjob = CommunicationOutJob.new
        newjob.params = payload
        newjob.result = api_res
        newjob.done = 100
        newjob.save
      end
      logger.info"result api = #{api_res}"
    end
  end

  def showcase_form
    # ToDo : gérer erreur retour api_call, msg_form_sent en conséquence
    if verify_recaptcha
      api_call('showcase_form_mail','','',params)
      flash.now[:notice] = t'demand_sent'
    else
      flash.now[:alert] = t'check_recaptcha'
    end
    respond_to do |format|
      format.js {render 'shared/showcase_form'}
      format.html {redirect_to :back}
    end
  end

  private

  def set_locale
    if params[:locale].blank? && current_user
      session[:locale] = current_user.setting[:language].blank? ? 'fr' : current_user.setting[:language]
    elsif !params[:locale].blank?
      current_user.setting.update_attribute(:language, params[:locale]) if current_user
      session[:locale] = params[:locale]
    elsif current_user
      session[:locale] = current_user.setting[:language].blank? ? 'fr' : current_user.setting[:language]
    else session[:locale] = 'fr'
    end
    I18n.locale = session[:locale]
  end

  def set_time_zone
    if current_user
      Time.zone = current_user.setting.time_zone unless current_user.setting.time_zone.blank?
    end
  end

  def load_cached_search_params
    if params[:saved_search_id]
      @current_params = SavedSearch.find(params[:saved_search_id]).criteria
    elsif (params[:search] && cached_params = Rails.cache.read(params[:search]))
      @current_params = cached_params
    else
      @current_params = params
      @current_params[:providers] ||= {}
      @current_params[:users] ||= {}
      @current_params[:titles] ||= {}
      @current_params[:pixtech_titles] ||= {}
    end
  end

  # envoi email erreur au support lors de la création d'un auteur PixTech
  def email_err(e, msg)
    AdminMailer.send_msg(I18n.t('new_creator_account',creator_word: session[:creator_word]),"#{Server.find_by_is_self(true).name} - #{msg} : Erreur #{e.inspect}").deliver_now
  end

  # envoi des json sur différents serveurs
  def send_scp_file(file, host, login, pwd, dest)
    begin
      Net::SCP.upload!(host, login, file, dest, ssh: { password: pwd })
    rescue => e
      email_err(e, " erreur envoi #{file} vers serveur #{host}")
      return false
    else
      return true
    end
  end

  def prepend_view_path_if_mobile
    prepend_view_path Rails.root + 'app' + 'views' + 'mobile_views' if mobile_browser?
  end

  def no_picto
    nop = 0
    if Server.itself? EDITIS_SERVER_NAME
      user_group = TitleProviderGroupName.joins(:titles).where(titles: {id: current_user.title_id}).first.name
      nop = 1 if EDITIS_NOPICTO_GROUPS.include?(user_group)
    end
    nop
  end

  def mobile_browser?
    request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod|iPad|Android)/]
  end
  helper_method :mobile_browser?

  # Création dossier MS
  def ms_init(string_key, login, pwd, stock, pixtech)
    if pixtech
      config_db_ms = Rails.configuration.database_configuration['ms_db']
      client = Mysql2::Client.new(host: config_db_ms['host'], database: config_db_ms['database'], username: config_db_ms['username'], password: config_db_ms['password'])

      row_add_prefix =  client.query("SELECT aap_agency_id from AgencyAdditionalPrefix where AgencyAdditionalPrefix.aap_prefix='#{stock}'")
      if row_add_prefix.count > 0
        agency_id = row_add_prefix.first['aap_agency_id']
        row =  client.query("SELECT inDir_path FROM InputDirectories where InputDirectories.inDir_agencyId=#{agency_id} and inDir_type = 6 limit 1")
      else
        row =  client.query("SELECT inDir_path FROM InputDirectories LEFT JOIN Agences on Agences.id=InputDirectories.inDir_agencyId where Agences.filePrefix='#{stock}' and inDir_type = 6 limit 1")
      end

      if row.first.nil?
        email_err('record not found', "Erreur lors de la création d'un auteur, enregistrement non trouvé dans les tables Agences et InputDirectories : Agences.filePrefix=#{stock} and InputDirectories.inDir_type = 6")
        client.close
        return false
      end
      inDir = row.first['inDir_path']
      client.close
      inDir.gsub!('/usr/PPserver/', '')
      username = login
      dossier = "#{inDir}/PHOTOGR38A17PH_#{string_key}"
      ftpdos = "in_pixtech/#{login}"
    else
      username = login
      dossier = "in_PH/#{login}"
      ftpdos = "in_PH/#{login}"
    end

    unless pwd.blank?
      config_ftp_ms = Rails.configuration.database_configuration['ftp_db']
      begin
        client = Mysql2::Client.new(host: config_ftp_ms['host'], database: config_ftp_ms['database'], username: config_ftp_ms['username'], password: config_ftp_ms['password'])
      rescue => e
        email_err(e, "Erreur lors de la connexion à la base vsftpd sur le MS, login : #{login}")
        client.close
        return false
      end
      begin
        client.query("INSERT INTO accounts (username, pass) VALUES ('#{username}', ENCRYPT('#{pwd}'))")
      rescue => e
        email_err(e, "Erreur lors de l'insertion dans la table accounts sur le MS, username : #{username}")
      ensure
        client.close
      end
    end
    tempfile = Tempfile.new("wb")
    tempfile.write("local_root=/home/vsftpd/#{dossier}")
    tempfile.rewind
    ftp_file = "/tmp/#{username}"
    File.open(ftp_file, "wb"){ |f| f.write(tempfile.read) }
    tempfile.close
    tempfile.unlink
    Net::SCP.upload!("ftp.pixtech.fr", "pix",
                     ftp_file, "/home/pix/temp/#{ftpdos}",
                     :ssh => { :password => "JeMetsUneCleSSH" })
    Net::SSH.start('ftp.pixtech.fr', 'pix', password: "JeMetsUneCleSSH") do |ssh|
      ssh.exec("mkdir -m 777 /usr/PPserver/#{dossier}")
    end
    # Net::SSH.start('ftp.pixtech.fr', 'pix', password: "JeMetsUneCleSSH") do |ssh|
    #   ssh_command="mkdir -m 777 /usr/PPserver/#{dossier}"
    #   ssh.exec("mkdir -m 777 /usr/PPserver/#{dossier}") do |ch, stream, data|
    #     logger.warn"******** Executing ssh command '#{ssh_command}'"
    #     if stream == :stderr
    #       logger.warn"******** Error while executing '#{ssh_command}' : #{data}"
    #     else
    #       logger.warn"******** ssh command executed (#{data})"
    #     end
    #   end
    # end

  end

  # pt création user, init sur serveur crawler
  def crawler_init(name_full)
    begin
      client = Mysql2::Client.new(host: '192.168.211.16', database: 'crawler', username: 'ptmanager', password: 'boh1gach')
    rescue => e
      email_err(e, " erreur crawler #{name_full}")
      return false
    end
    begin
      myquery = "insert into publicationconfig (name, keywords, period, status, maxresults, createdate, modifdate, crawltype_id, statusverif, domain_id) VALUES (
                          '#{name_full}', '#{name_full} photographe', 1, 2, 200, NOW(), NOW(), 1, 1, 0)"
      client.query(myquery)
    rescue => e
      email_err(e, " erreur crawler #{name_full}")
    end
    client.close
  end

  def marek_crypt(mastr)
    tostr = ''
    mastr_to_crypted = mastr.tr("A-Za-z", "N-ZA-Mn-za-m")
    mastr_to_crypted.split('').each do |c|
      randnum = rand(2)+1
      tostr += randnum.to_s
      randnum.times do
        dol = rand(54); nextdummy = (dol>26) ? rand(9).to_s : (rand(26)+64).chr
        tostr += nextdummy
      end
      if c == '/'
        tostr += '0'+rand(4).to_s
      elsif c == '@'
        tostr += '0'+(rand(4)+5).to_s
      elsif c == ' '
        tostr += '1'+rand(4).to_s
      elsif c == '.'
        tostr += '1'+(rand(4)+5).to_s
      else
        tostr += (rand(8)+2).to_s+c
      end
    end
    tostr
  end

  def marek_internal_decrypt(mastr)
    tostr = ''
    offset = 0
    scan = true
    while scan
      if  offset >= mastr.length
        break
      end
      skipChars = mastr[offset..offset].to_i
      offset += skipChars + 1
      if  offset >= (mastr.length - 1)
        tostr = ''
        break
      end
      if mastr[offset..offset] == '0'
        if mastr[offset+1..offset+1].to_i < 5
          tostr << '/'
        else
          tostr << '@'
        end
      elsif mastr[offset..offset] == '1'
        if mastr[offset+1..offset+1].to_i < 5
          tostr << ' '
        else
          tostr << '.'
        end
      else
        tostr << mastr[offset+1..offset+1]
      end
      offset += 2
      scan = false if mastr[offset].nil?
    end
    tostr.tr("A-Za-z", "N-ZA-Mn-za-m")
  end

  def marek_decrypt(inMSpicID,prov_strkey='')
    deStr = marek_internal_decrypt(inMSpicID)
    if deStr.empty?
      deStr = inMSpicID if (Integer(inMSpicID) rescue false)
    else
      if (Integer(deStr) rescue false)
        if (deStr.length <= 3) and not (prov_strkey == 'Cosmos')
          if (Integer(inMSpicID) rescue false)
            deStr = inMSpicID
          else
            deStr = ''
          end
        end
      else
        if (Integer(inMSpicID) rescue false)
          deStr = inMSpicID
        else
          deStr = ''
        end
      end
    end
    deStr
  end

  def marek_request_build(ms_pic_id)
    params = []
    params << '9Pu0NkL41'
    params << ms_pic_id
    params << current_user.title.server.name
    params << request.remote_ip
    params << current_user.title.name
    params << current_user.login
    marek_crypt(params.join('@@@'))
  end

  def simplifize(text)
    I18n.transliterate(text.to_s.force_encoding('UTF-8')).gsub(/[^a-zA-Z0-9]/, '')
  end

  def date_to_db_format(date_value)
    Date.strptime(date_value,I18n.t('date.formats.default')).to_s(:db) rescue '' unless date_value.blank?
  end

end