#!/usr/bin/env python3

import tempfile
import subprocess
import os
import shutil
import sys

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from pypdf import PdfReader, PdfWriter

PAGE_WIDTH, PAGE_HEIGHT = A4

# =========================
# CONFIGURAÇÃO
# =========================

PFX_PATH = "certificado.pfx"
PFX_PASS = "senhaPfx"

PDF_CONTRATO = "CONTRATO LOCAÇAO APTO JESSICA.pdf"
ASSINATURA_IMG = "assinatura.png"

PDF_FINAL = "CONTRATO_FINAL.pdf"
ASSINATURA_FINAL = "CONTRATO_FINAL.pdf.p7s"


# =========================
# FUNÇÕES OPENSSL
# =========================

def run_cmd(cmd):
    try:
        subprocess.run(cmd, check=True)
    except subprocess.CalledProcessError as e:
        print("Erro ao executar:", cmd)
        raise


def extract_from_pfx(pfx_path, pfx_pass, out_dir):

    key_path = os.path.join(out_dir, "key.pem")
    certs_path = os.path.join(out_dir, "certs.pem")

    run_cmd([
        "openssl","pkcs12",
        "-in",pfx_path,
        "-nocerts",
        "-nodes",
        "-passin",f"pass:{pfx_pass}",
        "-out",key_path
    ])

    run_cmd([
        "openssl","pkcs12",
        "-in",pfx_path,
        "-nokeys",
        "-passin",f"pass:{pfx_pass}",
        "-out",certs_path
    ])

    return key_path, certs_path


def sign_pdf(pdf_path, pfx_path, pfx_pass, outfile):

    with tempfile.TemporaryDirectory() as td:

        key_pem, certs_pem = extract_from_pfx(pfx_path, pfx_pass, td)

        cmd = [
            "openssl","cms","-sign",
            "-binary",
            "-in", pdf_path,
            "-signer", certs_pem,
            "-inkey", key_pem,
            "-outform","DER",
            "-out", outfile,
            "-nosmimecap",
            "-md","sha256",
            "-detached"
        ]

        run_cmd(cmd)


# =========================
# GERAR CARD PDF
# =========================

def gerar_card(temp_pdf, dados):

    c = canvas.Canvas(temp_pdf, pagesize=A4)

    y = PAGE_HEIGHT - 40
    altura_card = 100

    c.rect(20, y - altura_card, PAGE_WIDTH - 40, altura_card)

    c.setFont("Helvetica-Bold", 11)
    c.drawString(30, y - 20, dados["nome"])

    c.setFont("Helvetica", 9)

    linhas = [
        f"IP: {dados['ip']}",
        f"Dispositivo: {dados['device']}",
        f"Data e hora: {dados['data']}",
        f"E-mail: {dados['email']}",
        f"Telefone: {dados['telefone']}",
        f"Token: {dados['token']}"
    ]

    yy = y - 35

    for linha in linhas:
        c.drawString(30, yy, linha)
        yy -= 12

    c.drawImage(
        ASSINATURA_IMG,
        PAGE_WIDTH - 180,
        y - 85,
        width=170,
        height=70,
        preserveAspectRatio=True
    )

    c.save()


# =========================
# MESCLAR PDF
# =========================

def gerar_pdf_final():

    temp_pdf = "card_temp.pdf"

    dados = {
        "nome": "VITOR HUGO PINHEIRO BICCA",
        "ip": "111.111.111.111",
        "device": "Android",
        "data": "12/03/2026",
        "email": "vitor.bicca@gmail.com",
        "telefone": "5547996623966",
        "token": "****"
    }

    gerar_card(temp_pdf, dados)

    reader_original = PdfReader(PDF_CONTRATO)
    reader_card = PdfReader(temp_pdf)

    writer = PdfWriter()

    for page in reader_original.pages:
        writer.add_page(page)

    for page in reader_card.pages:
        writer.add_page(page)

    with open(PDF_FINAL, "wb") as f:
        writer.write(f)

    os.remove(temp_pdf)


# =========================
# MAIN
# =========================

def main():

    if shutil.which("openssl") is None:
        print("OpenSSL não encontrado")
        sys.exit(1)

    print("Gerando PDF...")
    gerar_pdf_final()

    print("Assinando PDF...")
    sign_pdf(PDF_FINAL, PFX_PATH, PFX_PASS, ASSINATURA_FINAL)

    print("\nArquivos gerados:")
    print("PDF:", PDF_FINAL)
    print("Assinatura:", ASSINATURA_FINAL)
    print("\nValide em: https://validar.iti.gov.br")


if __name__ == "__main__":
    main()