# Copyright 2015 PerfKitBenchmarker Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Class to represent a Rackspace Virtual Machine object.

Zones:
    DFW (Dallas-Fort Worth)
    IAD (Northern Virginia)
    ORD (Chicago)
    LON (London)
    SYD (Sydney)
    HKG (Hong Kong)
Machine Types:
run 'rack servers flavor list'
Images:
run 'rack servers image list'

All VM specifics are self-contained and the class provides methods to
operate on the VM: boot, shutdown, etc.
"""

from collections import OrderedDict
import json
import logging
import re
import tempfile
from absl import flags
from perfkitbenchmarker import errors
from perfkitbenchmarker import linux_virtual_machine
from perfkitbenchmarker import providers
from perfkitbenchmarker import virtual_machine
from perfkitbenchmarker import vm_util
from perfkitbenchmarker.configs import option_decoders
from perfkitbenchmarker.providers.rackspace import rackspace_disk
from perfkitbenchmarker.providers.rackspace import rackspace_network
from perfkitbenchmarker.providers.rackspace import util
import six
from six.moves import range
from six.moves import zip

FLAGS = flags.FLAGS

CLOUD_CONFIG_TEMPLATE = '''#cloud-config
users:
  - name: {0}
    ssh-authorized-keys:
      - {1}
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash

'''

BLOCK_DEVICE_TEMPLATE = '''
source-type=image,
source-id={0},
dest=volume,
size={1},
shutdown=remove,
bootindex=0
'''

LSBLK_REGEX = (r'NAME="(.*)"\s+MODEL="(.*)"\s+SIZE="(.*)"'
               r'\s+TYPE="(.*)"\s+MOUNTPOINT="(.*)"\s+LABEL="(.*)"')
LSBLK_PATTERN = re.compile(LSBLK_REGEX)

INSTANCE_EXISTS_STATUSES = frozenset(
    ['BUILD', 'ACTIVE', 'PAUSED', 'SHUTOFF', 'ERROR'])
INSTANCE_DELETED_STATUSES = frozenset(
    ['DELETED'])
INSTANCE_KNOWN_STATUSES = INSTANCE_EXISTS_STATUSES | INSTANCE_DELETED_STATUSES

REMOTE_BOOT_DISK_SIZE_GB = 50


def RenderBlockDeviceTemplate(image, volume_size):
  """Renders template used for the block-device flag in RackCLI.

  Args:
    image: string. Image ID of the source image.
    volume_size: string. Size in GB of desired volume size.

  Returns:
    string value for block-device parameter used when creating a VM.
  """
  blk_params = BLOCK_DEVICE_TEMPLATE.replace('\n', '').format(
      image, str(volume_size))
  return blk_params


class RackspaceVmSpec(virtual_machine.BaseVmSpec):
  """Object containing the information needed to create a