"""
  Machine models for atmosphere.
"""
import json
import re
import os

from django.db import models
from django.db.models import Q, Model
from django.core.exceptions import ValidationError
from django.utils import timezone
from core.models.user import AtmosphereUser as User

from core.models.application import create_application, ApplicationThreshold
from core.models.license import License
from core.models.boot_script import BootScript
from core.models.machine import ProviderMachine
from core.models.node import NodeController
from core.models.provider import Provider
from core.models.identity import Identity
from core.models.application_version import ApplicationVersion

from atmosphere.settings import secrets
from threepio import logger
from core.models.abstract import BaseRequest
from core.exceptions import RequestLimitExceeded
from functools import reduce

UNRESOLVED_STATES = ["pending", "processing", "validated", "failed"]


class MachineRequest(BaseRequest):

    """
    Storage container for the MachineRequestThread to start/restart the Queue
    Provides a Parent-Child relationship between the new image and ancestor(s)
    """

    # The instance to image.
    instance = models.ForeignKey("Instance")

    old_status = models.TextField(default="", null=True, blank=True)

    # Machine imaging Metadata
    parent_machine = models.ForeignKey(ProviderMachine,
                                       related_name="ancestor_machine")

    # Data for the new machine, version and app...
    # Application specific:
    new_application_name = models.CharField(max_length=256)
    new_application_description = models.TextField(
        default='Description Missing')
    new_application_visibility = models.CharField(
        max_length=256, default='private')  # Choices:Public, Private, Select
    access_list = models.TextField(
        default='',
        blank=True,
        null=True)  # DEPRECATED in API v2
    # SPECIFIC to 'forked=False'

    # Specific to ApplicationVersion && ProviderMachine
    system_files = models.TextField(default='', blank=True, null=True)
    installed_software = models.TextField(default='', blank=True, null=True)
    exclude_files = models.TextField(default='', blank=True, null=True)
    new_version_name = models.CharField(max_length=256, default='1.0')
    new_version_change_log = models.TextField(default='Changelog Missing')
    new_version_tags = models.TextField(