#!/usr/bin/env python
# encoding: utf-8
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.from gcloud import app

import json
import urllib
import collections

from flask import jsonify, request, url_for

from gstack import app, publickey_storage
from gstack import authentication
from gstack import helpers
from gstack import controllers
from gstack.services import requester
from gstack.controllers import errors


def _get_account_by_name(authorization, projectid):
    args = {'command': 'listAccounts'}
    return controllers.get_item_with_name(authorization, projectid, args, 'account')


def _list_ssh_keys(authorization):
    command = 'listTags'
    args = {
        'resourcetype': 'UserVm',
        'keyword': 'sshkey-segment'
    }

    cloudstack_response = requester.make_request(
        command,
        args,
        authorization.client_id,
        authorization.client_secret
    )

    resources = {}
    sshkeys = set()

    if cloudstack_response['listtagsresponse']:
        for tag in cloudstack_response['listtagsresponse']['tag']:
            if tag['resourceid'] not in resources:
                resources[tag['resourceid']] = {}
            resources[tag['resourceid']][tag['key']] = tag['value']
        for resource in resources:
            sorted_resource = collections.OrderedDict(
                sorted(
                    resources[resource].items()))
            sshkey = ''
            for keychunk in sorted_resource:
                sshkey = sshkey + sorted_resource[keychunk]
            sshkeys.add(sshkey)

    sshkeys = '\n'.join(sshkeys)

    return sshkeys


def _format_quota(metric, limit, usage):
    quota = {}
    quota['metric'] = metric
    quota['limit'] = limit
    quota['usage'] = usage
    return quota


def _populate_quotas(cloudstack_response):
    quotas = []

    quota_names = {}
    quota_names['INSTANCE'] = 'vm'
    quota_names['DISKS'] = 'volume'
    quota_names['SNAPSHOTS'] = 'snapshot'
    quota_names['IMAGES'] = 'template'

    for name in quota_names:
        quotas.append(
            _format_quota(
                name,
                cloudstack_response[quota_names[name] + 'limit'],
                cloudstack_response[quota_names[name] + 'total']
            )
        )

    return quotas


def _cloudstack_project_to_gce(cloudstack_response, metadata=None):
    if not metadata:
        metadata = {}

    quotas = _populate_quotas(cloudstack_response)

    response = {}
    response['kind'] = 'compute#project'
    response['id'] = cloudstack_response['id']
    response['creationTimestamp'] = cloudstack_response['user'][0]['created']
    response['name'] = cloudstack_response['name']
    response['description'] = cloudstack_response['name']
    response['selfLink'] = request.base_url

    if metadata:
        response['commonInstanceMetadata'] = {}
        response['commonInstanceMetadata']['kind'] = 'compute#metadata'
        response['commonInstanceMetadata']['items'] = []

    if quotas:
        response['quotas'] = quotas

    if 'sshKeys' in metadata and metadata['sshKeys']:
        sshKeys = {}
        sshKeys['key'] = 'sshKeys'
        sshKeys['value'] = metadata['sshKeys']
        response['commonInstanceMetadata']['items'].append(sshKeys)

    return response


@app.route('/compute/v1/projects/<projectid>', methods=['GET'])
@authentication.required
def getproject(authorization, projectid):
    project = _get_account_by_name(authorization, projectid)

    if project:
        metadata = {}
        metadata['sshKeys'] = _list_ssh_keys(authorization)
        publickey_storage[projectid] = metadata['sshKeys']

        res = jsonify(_cloudstack_project_to_gce(project, metadata))
        res.status_code = 200
    else:
        func_route = urllib.unquote_plus(
            url_for(
                'getproject',
                projectid=projectid))
        res = errors.resource_not_found(func_route)

    return res


@app.route('/compute/v1/projects/<projectid>/setCommonInstanceMetadata', methods=['POST'])
@authentication.required
def setglobalmetadata(projectid, authorization):
    data = json.loads(request.data)
    publickey_storage[projectid] = data['items'][0]['value']
    data = data['items'][0]['value'].split(':')[1]

    command = 'deleteSSHKeyPair'
    args = {
        'name': projectid
    }

    requester.make_request(
        command,
        args,
        authorization.client_id,
        authorization.client_secret,
    )

    command = 'registerSSHKeyPair'
    args = {
        'name': projectid,
        'publickey': data
    }

    requester.make_request(
        command,
        args,
        authorization.client_id,
        authorization.client_secret,
    )

    res = jsonify({
        "kind": "compute#operation",
        'operationType': 'setMetadata',
        'targetLink': urllib.unquote_plus(helpers.get_root_url() + url_for(
            'getproject',
            projectid=projectid
        )),
        'status': 'PENDING',
        'progress': 0
    })
    res.status_code = 200
    return res
