<?php

namespace App\Services\CloudAssets\Aws;

use App\Models\CloudAsset;
use App\Services\Integrations\CloudAssets\AwsIntegration;

class AwsCloudAssetsSyncService
{
    protected $apiService;

    /**
     * Constructor for the class.
     *
     * @param AwsIntegration $apiService
     */
    public function __construct(AwsIntegration $apiService)
    {
        $this->apiService = $apiService;
    }

    /**
     * Save instances from the API response.
     *
     * @param mixed $apiResponse
     * @param string $region
     *
     * @return void
     */
    public function saveInstances($apiResponse, $region): void
    {
        foreach ($apiResponse['Reservations'] as $reservation) {
            foreach ($reservation['Instances'] as $instance) {
                CloudAsset::create($this->getInstanceSaveData($instance, $region));
            }
        }
    }

    /**
     * Retrieves the save data for an instance.
     *
     * @param mixed $instance The instance object.
     * @param string $region The region.
     * @return array The save data for the instance.
     */
    private function getInstanceSaveData($instance, $region): array
    {
        $NameIndex = array_search('Name', array_column($instance['Tags'], 'Key'));
        $name = $instance['Tags'][$NameIndex]['Value'] ?? '';

        return [
            'name' => $name,
            'identifier' => $instance['InstanceId'],
            'instance_state' => $instance['State']['Name'],
            'instance_type' => $instance['InstanceType'],
            'availability_zone' => $region,
            'launched_date' => $instance['LaunchTime'],
            'cloud_asset_type' => 'instance',
        ];
    }

    /**
     * Save RDS instances from an API response.
     *
     * @param array $apiResponse The API response containing the RDS instances.
     * @param string $region The region.
     * @return void
     */
    public function saveRds($apiResponse, $region): void
    {
        foreach ($apiResponse['DBInstances'] as $instance) {
            CloudAsset::create($this->getRdsSaveData($instance, $region));
        }
    }

    /**
     * Generates an array of RDS save data from the given instance and cloud asset type.
     *
     * @param mixed $instance The instance data.
     * @param string $region
     * @return array The generated RDS save data.
     */
    public function getRdsSaveData($instance, $region): array
    {
        return [
            'name' => $instance['DBInstanceClass'],
            'identifier' => $instance['DBInstanceClass'],
            'instance_state' => $instance["ActivityStreamStatus"],
            'instance_type' => $instance['DBInstanceIdentifier'],
            'availability_zone' => $region,
            'launched_date' => $instance['InstanceCreateTime'],
            'cloud_asset_type' => 'rds',
        ];
    }

    /**
     * Saves S3 buckets to the database.
     *
     * @param array $apiResponse The API response containing the buckets to be saved.
     * @param string $region The region of the buckets.
     * @return void
     */
    public function saveS3Buckets($apiResponse, string $region): void
    {
        foreach ($apiResponse['Buckets'] as $bucket) {
            // Fetching individual bucket's location
            $bucketRegion = $this->apiService->getS3BucketLocation($bucket['Name'], $region);
            CloudAsset::create($this->getS3BucketSaveData($bucket, $bucketRegion));
        }
    }

    /**
     * Retrieves the save data for an S3 bucket.
     *
     * @param string $bucket The bucket name.
     * @param string $bucketRegion The bucket region.
     * @return array The save data for the S3 bucket.
     */
    public function getS3BucketSaveData($bucket, string $bucketRegion): array
    {
        return [
            'name' => $bucket['Name'],
            'availability_zone' => $bucketRegion,
            'launched_date' => $bucket['CreationDate'],
            'cloud_asset_type' => 's3',
        ];
    }
}