# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""Tests that verify MMDS related functionality."""

import json
import random
import string
import time
import pytest
from framework.artifacts import DEFAULT_DEV_NAME, NetIfaceConfig
from framework.builder import MicrovmBuilder, SnapshotBuilder, SnapshotType
from framework.utils import generate_mmds_session_token, \
    generate_mmds_v2_get_request

import host_tools.network as net_tools

# Minimum lifetime of token.
MIN_TOKEN_TTL_SECONDS = 1
# Maximum lifetime of token.
MAX_TOKEN_TTL_SECONDS = 21600
# Default IPv4 value for MMDS.
DEFAULT_IPV4 = '169.254.169.254'
# MMDS versions supported.
MMDS_VERSIONS = ['V2', 'V1']


def _assert_out(stdout, stderr, expected):
    assert stderr.read() == ''
    assert stdout.read() == expected


def _populate_data_store(test_microvm, data_store):
    response = test_microvm.mmds.get()
    assert test_microvm.api_session.is_status_ok(response.status_code)
    assert response.json() == {}

    response = test_microvm.mmds.put(json=data_store)
    assert test_microvm.api_session.is_status_no_content(response.status_code)

    response = test_microvm.mmds.get()
    assert test_microvm.api_session.is_status_ok(response.status_code)
    assert response.json() == data_store


def _configure_mmds(test_microvm, iface_id, version, ipv4_address=None):
    mmds_config = {
        'version': version,
        'network_interfaces': [iface_id]
    }

    if ipv4_address:
        mmds_config['ipv4_address'] = ipv4_address

    response = test_microvm.mmds.put_config(json=mmds_config)
    assert test_microvm.api_session.is_status_no_content(response.status_code)


@pytest.mark.parametrize(
    "version",
    MMDS_VERSIONS
)
def test_custom_ipv4(test_microvm_with_api, network_config, version):
    """
    Test the API for MMDS custom ipv4 support.

    @type: functional
    """
    test_microvm = test_microvm_with_api
    test_microvm.spawn()

    data_store = {
        'latest': {
            'meta-data': {
                'ami-id': 'ami-12345678',
                'reservation-id': 'r-fea54097',
                'local-hostname': 'ip-10-251-50-12.ec2.internal',
                'public-hostname': 'ec2-203-0-113-25.compute-1.amazonaws.com',
                'network': {
                    'interfaces': {
                        'macs': {
                            '02:29:96:8f:6a:2d': {
                                'device-number': '13345342',
                                'local-hostname': 'localhost',
                                'subnet-id': 'subnet-be9b61d'
                            }
                        }
                    }
                }
            }
        }
    }
    _populate_data_store(test_microvm, data_store)

    # Attach network device.
    _tap = test_microvm.ssh_network_config(network_config, '1')

    # Invalid values IPv4 address.
    response = test_microvm.mmds.put_config(json={
        'ipv4_address': '',
        'network_interfaces': ['1']
    })
    assert test_microvm.api_session.is_status_bad_request(response.status_code)

    response = test_microvm.mmds.put_config(json={
        'ipv4_address': '1.1.1.1',
        'network_interfaces': ['1']
    })
    assert test_microvm.api_session.is_status_bad_request(response.status_code)

    ipv4_address = '169.254.169.250'
    # Configure MMDS with custom IPv4 address.
    _configure_mmds(
        test_microvm,
        iface_id='1',