# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/

class Integration::PGPController < ApplicationController
  prepend_before_action { authentication_check && authorize! }

  def public_key_download
    cert = PGPKeypair.find(params[:id])

    send_data(
      cert.public_key,
      filename: "#{cert.fingerprint}.asc",
      type: 'text/plain',
      disposition: 'attachment'
    )
  end

  def private_key_download
    cert = PGPKeypair.find(params[:id])

    send_data(
      cert.private_key,
      filename: "#{cert.fingerprint}-private.asc",
      type: 'text/plain',
      disposition: 'attachment'
    )
  end

  def public_key_list
    render json: PGPKeypair.all, methods: :email_addresses
  end

  def public_key_delete
    PGPKeypair.find(params[:id]).destroy!
    render json: {
      result: 'ok'
    }
  end

  def public_key_add
    string = params[:data]
    string = params[:file].read.force_encoding('utf-8') if string.blank? && params[:file].present?

    items = PGPKeypair.create_public_keys(string)

    render json: {
      result: 'ok',
      response: items
    }
  rescue StandardError => e
    unprocessable_entity(e)
  end

  def private_key_delete
    PGPKeypair.find(params[:id]).update!(
      private_key: nil,
      private_key_secret: nil
    )

    render json: {
      result: 'ok'
    }
  end

  def private_key_add
    string = params[:data]
    string = params[:file].read.force_encoding('utf-8') if string.blank? && params[:file].present?

    raise "Parameter 'data' or 'file' required." if string.blank?

    PGPKeypair.create_private_keys(string, params[:secret])

    render json: {
      result: 'ok'
    }
  rescue StandardError => e
    unprocessable_entity(e)
  end

  def search
    result = {
      type: 'PGP'
    }

    result[:encryption] = article_encryption(params[:article])
    result[:sign]       = article_sign(params[:ticket])

    render json: result
  end

  def article_encryption(article)
    result = {
      success: false,
      comment: 'no recipient found'
    }

    return result if article.blank?
    return result if article[:to].blank? && article[:cc].blank?

    recipient  = [article[:to], article[:cc]].compact.join(',').to_s
    recipients = []
    begin
      list = Mail::AddressList.new(recipient)
      list.addresses.each do |address|
        recipients.push address.address
      end
    rescue StandardError # rubocop:disable Lint/SuppressedException
    end

    return result if recipients.blank?

    begin
      keys = PGPKeypair.for_recipient_email_addresses!(recipients)

      if keys
        result[:success] = true
        result[:comment] = "keys found for #{recipients.join(',')}"
      end
    rescue StandardError => e
      result[:comment] = e.message
    end

    result
  end

  def article_sign(ticket)
    result = {
      success: false,
      comment: 'key not found'
    }

    return result if ticket.blank? || !ticket[:group_id]

    group = Group.find_by(id: ticket[:group_id])
    return result unless group

    email_address = group.email_address
    begin
      list = Mail::AddressList.new(email_address.email)
      from = list.addresses.first.to_s
      key = PGPKeypair.for_sender_email_address(from)
      if key
        result[:success] = true
        result[:comment] = "key for #{email_address.email} found"
      else
        result[:success] = false
        result[:comment] = "no key for #{email_address.email} found"
      end
    rescue StandardError => e
      result[:comment] = e.message
    end

    result
  end
end
