<?php

namespace App\Services;

use Illuminate\Support\Facades\DB;

class MalwareAnalysisService
{
    public function scanFile($filePath)
    {
        $fileType = $this->getFileType($filePath);
        $results = [];

        $results['hashAnalysis'] = $this->performHashAnalysis($filePath);
        $results['yaraAnalysis'] = $this->performYaraAnalysis($filePath);

        switch ($fileType) {
            case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
            case 'application/vnd.ms-excel':
            case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
            case 'application/vnd.ms-powerpoint':
            case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
                $results['officeAnalysis'] = $this->analyzeOfficeDocuments($filePath);
                break;
            case 'application/pdf':
                $results['pdfAnalysis'] = $this->analyzePDFs($filePath);
                break;
            default:
                $results['stringAnalysis'] = $this->extractAndAnalyzeStrings($filePath);
                $results['codeDisassembly'] = $this->performCodeDisassembly($filePath);
                break;
        }

        $isSafe = $this->interpretResults($results);

        return ['isSafe' => $isSafe, 'details' => $results];
    }

    protected function getFileType($filePath) {
        $fileType = shell_exec("file -b --mime-type " . escapeshellarg($filePath));
        return trim($fileType);
    }

    protected function performHashAnalysis($filePath) {
        $fileHash = hash_file('sha256', $filePath);
        // $knownMalwareHashes = $this->loadHashesFromVirusShare();
        // if (in_array($fileHash, $knownMalwareHashes)) {
        //     return true;
        // }

        return $this->queryHybridAnalysis($fileHash);
    }

    // protected function loadHashesFromVirusShare() {
    //     $hashes = DB::table('malware_hashes')->pluck('hash')->toArray();

    //     return $hashes;
    // }

    protected function queryHybridAnalysis($hash) {
        $apiKey = '4sq2chus75cbcca040jiw2kz4788b2abjyxh542d7d1a3c71a885mreje98b9850';
        $url = "https://www.hybrid-analysis.com/api/v2/search/hash/{$hash}";

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "api-key: {$apiKey}",
            "accept: application/json"
        ]);

        $response = curl_exec($ch);
        curl_close($ch);

        if (!$response) {
            return false;
        }

        $data = json_decode($response, true);
        return !empty($data['data']);
    }

    protected function analyzeOfficeDocuments($filePath) {
        $command = "python3 -m oletools.olevba " . escapeshellarg($filePath);
        $output = shell_exec($command);
    }

    protected function analyzePDFs($filePath) {
        $command = "peepdf " . escapeshellarg($filePath);
        $output = shell_exec($command);
    }

    protected function performYaraAnalysis($filePath) {
        $rules = [
            resource_path('yara/malware/000_common_rules.yar'),
            resource_path('yara/exploit_kits/EK_Angler.yar'),
            resource_path('yara/webshells/WShell_APT_Laudanum.yar'),
        ];

        $rulesPath = implode(" ", $rules);
        $command = "yara $rulesPath " . escapeshellarg($filePath);
        $output = shell_exec($command);

        return !empty($output);
    }


    protected function extractAndAnalyzeStrings($filePath) {
        $command = "strings $filePath";
        $stringsOutput = shell_exec($command);

        $suspiciousPatterns = ['/maliciousurl\.com/', '/192\.168\.0\.1/'];
        foreach ($suspiciousPatterns as $pattern) {
            if (preg_match($pattern, $stringsOutput)) {
                return true;
            }
        }

        return false;
    }

    protected function performCodeDisassembly($filePath) {
        $fileType = shell_exec("file " . escapeshellarg($filePath));

        // verificar se o arquivo é um executável ELF ou PE
        if (strpos($fileType, 'ELF') !== false || strpos($fileType, 'PE') !== false) {
            $command = "objdump -d " . escapeshellarg($filePath);
            $disassemblyOutput = shell_exec($command);

            $suspiciousPatterns = [
                '/call.*0x/', // Chamadas para endereços possivelmente calculados (indicativo de shellcode)
                '/jmp.*0x/',  // Saltos para endereços possivelmente calculados
                '/int 0x80/', // Interrupções do Linux para chamadas de sistema (syscall)
                '/syscall/',  // Instrução de chamada de sistema no x86_64
            ];

            foreach ($suspiciousPatterns as $pattern) {
                if (preg_match($pattern, $disassemblyOutput)) {
                    return true;
                }
            }
        }

        return false;
    }

    protected function interpretResults($results) {
        foreach ($results as $result) {
            if ($result) return false;
        }

        return true;
    }

}
