<?php

namespace App\Services\Security\Crowdstrike\Reports;

abstract class AbstractCrowdstrikeService
{
    abstract public function data();
    abstract public function exportData();


    /**
     * Executing the query
     * @param $mainQuery Query
     * @param string $order field name for sort
     * @param string $sortDirection direction for sort
     * 
     * @return Query Result
     */
    public function getOutputData($mainQuery, $order, $sortDirection)
    {
        $start = request('start');
        $limit = request('length');
        
        if ($limit != -1) {
            $mainQuery = $mainQuery->offset($start)->limit($limit);
        }
        
        $mainQuery->orderBy($order, $sortDirection);

        return $mainQuery->get();
    }

    /**
     * Filer the main query based on filters
     *
     * @param object $mainQuery DB Query
     * @param array  $inputData Filter data
     * @param string $reportType type of the report
     *
     * @return Query
     */
    public function filterResults($mainQuery, $inputData)
    {
        $vulnerabilityFields = ['asset_id', 'cve_id', 'exprt_rating', 'severity', 'product_name_normalized', 'product_name_version', 'days_open', 'base_score', 'vulnerability_count'];
        $vulnerabilitiessAssetsFields = ['asset_tag', 'serial_no', 'asset_status_id', 'make_and_model_id', 'technical_spec_id', 'user_id', 'location_id'];
        $vulnerabilitiesAssetsUserFields = ['city'];
        $vulnerabilitiesDateRangeMatchFields = ['cve_published_from', 'cve_published_to'];

        foreach ($inputData as $filterKey => $filterValue) {

            if ($filterValue == '') {
                continue;
            }

            if (in_array($filterKey, $vulnerabilityFields)) {
                $mainQuery = $this->repository->filterWithVulnerabilityFields($mainQuery, $filterKey, $filterValue);
            }

            if (in_array($filterKey, $vulnerabilitiessAssetsFields)) {
                $mainQuery = $this->repository->filterWithVulnerabilitysAssetFields($mainQuery, $filterKey, $filterValue);
            }

            if (in_array($filterKey, $vulnerabilitiesAssetsUserFields)) {
                $mainQuery = $this->repository->filterWithVulnerabilitysAssetsUserFields($mainQuery, $filterKey, $filterValue);
            }

            if (in_array($filterKey, $vulnerabilitiesDateRangeMatchFields)) {
                $mainQuery = $this->repository->filterVulnerabilityDateRangeMatch($mainQuery, $filterKey, $filterValue);
            }
            
        }
        
        return $mainQuery;
    }

    /**
     * Generating data table data from qurey result
     * @param $mainQuery Query Result
     * @param $start Starting index
     * @param $data Collection valriable that will return
     *
     * @return array
     */
    public function getReportData($mainQuery, $start, $data = [])
    {
        $parentIndex = $start;

        foreach ($mainQuery as $key => $singleRecord) {
            $parentIndex++;
            $nestedData = $this->getNestedData($singleRecord, $parentIndex);
            $data[] = $nestedData;
        }

        return $data;
    }

    /**
     * get sort option for the table
     * 
     * @return array
     */
    public function getSortOptions()
    {
        $customColumns = [
            'product_name' => 'product_name_normalized',
            'product_version' => 'product_name_version',
            'days_open' => 'opened_at',
        ];
        $column = request('order.0.column');
        $sortColumn = request('columns.' . $column . '.data') ?? 'id';
        $direction = request('order.0.dir') ?? 'desc';

        foreach ($customColumns as $key => $customColumn) {
             
            if ($key == $sortColumn) {
                $sortColumn = $customColumn;
            }
        }
        
        return ['column' => $sortColumn, 'direction' => $direction];
    }

    /**
     * Generating data to export
     * 
     * @param $mainQuery Query Result
     * @param $data Collection valriable that will return
     * @param $requiredColumns colums to be shown in export file

     * @return array
     */
    public function getReportExportData($mainQuery, $data)
    {
        foreach ($mainQuery as $singleRecord) {
            $nestedData = $this->getExportNestedData($singleRecord);
            $data[] = $nestedData;
        }

        return $data;
    }

}