# Copyright 2016, 2017 John J. Rofrano. 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
#
# https://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.

import os
from threading import Lock
from flask import Flask, Response, jsonify, request, json

# Create Flask application
app = Flask(__name__)

# Status Codes
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_204_NO_CONTENT = 204
HTTP_400_BAD_REQUEST = 400
HTTP_404_NOT_FOUND = 404
HTTP_409_CONFLICT = 409

# Lock for thread-safe counter increment
lock = Lock()

######################################################################
# GET INDEX
######################################################################
@app.route('/')
def index():
    recommendations_url = request.base_url + "recommendations"
    return jsonify(name='Recommendations REST API Service',
                   version='0.1',
                   url=recommendations_url
                   ), HTTP_200_OK

######################################################################
# LIST ALL PRODUCT RECOMMENDATIONS
######################################################################
@app.route('/recommendations', methods=['GET'])
def list_recommendations():
    """
    Basically prints out all the recommendations.
    """

    message = {}
    for prod_id in data:
        message[prod_id] = {'data': [{'id': x['id'],
                                      'name': x['name']} for x in
                                     data[prod_id]['recommendations']],
                            'id': prod_id,
                            'name': data[prod_id]['name']}
    return reply(message, HTTP_200_OK)

######################################################################
# RETRIEVE A PET
######################################################################
@app.route('/recommendations/<id>', methods=['GET'])
def get_recommendations(id):
    '''
    Given a Product ID, Output a list of it's reccommendations.
    '''

    if id in data:
        recomms = data[id]['recommendations']
        rc = HTTP_200_OK
    else:
        recomms = {'error': 'Product with id: %s was not found' % str(id)}
        rc = HTTP_404_NOT_FOUND

    return reply(recomms, rc)

######################################################################
# ADD A NEW PET
######################################################################
@app.route('/pets', methods=['POST'])
def create_pets():
    payload = request.get_json()
    if is_valid(payload):
        id = next_index()
        pets[id] = {'id': id, 'name': payload['name'], 'kind': payload['kind']}
        message = pets[id]
        rc = HTTP_201_CREATED
    else:
        message = { 'error' : 'Data is not valid' }
        rc = HTTP_400_BAD_REQUEST

    return reply(message, rc)

######################################################################
# UPDATE AN EXISTING PET
######################################################################
@app.route('/pets/<int:id>', methods=['PUT'])
def update_pets(id):
    if pets.has_key(id):
        payload = request.get_json()
        if is_valid(payload):
            pets[id] = {'id': id, 'name': payload['name'], 'kind': payload['kind']}
            message = pets[id]
            rc = HTTP_200_OK
        else:
            message = { 'error' : 'Pet data was not valid' }
            rc = HTTP_400_BAD_REQUEST
    else:
        message = { 'error' : 'Pet %s was not found' % id }
        rc = HTTP_404_NOT_FOUND

    return reply(message, rc)

######################################################################
# DELETE A PRODUCT RECOMMENDATION
######################################################################
@app.route('/recommendations/<id>', methods=['DELETE'])
def delete_recommendations(id):
    if id in data:
        del data[id]
    return '', HTTP_204_NO_CONTENT

######################################################################
#  U T I L I T Y   F U N C T I O N S
######################################################################
def next_index():
    global current_pet_id
    with lock:
        current_pet_id += 1
    return current_pet_id

def reply(message, rc):
    response = Response(json.dumps(message))
    response.headers['Content-Type'] = 'application/json'
    response.status_code = rc
    return response

def is_valid(data):
    valid = False
    try:
        name = data['name']
        kind = data['kind']
        valid = True
    except KeyError as err:
        app.logger.error('Missing parameter error: %s', err)
    return valid


######################################################################
#   M A I N
######################################################################
if __name__ == "__main__":
    SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
    dummy_json_url = os.path.join(SITE_ROOT, "dummy/",
        "dummy_product_recomm.json")
    data = json.load(open(dummy_json_url))
    # Pull options from environment
    debug = (os.getenv('DEBUG', 'False') == 'True')
    port = os.getenv('PORT', '5000')
    app.run(host='0.0.0.0', port=int(port), debug=debug)

@@ -692,16 +692,28 @@
 st, json
+%0Aimport uuid
 %0A%0A# Crea
@@ -2605,32 +2605,40 @@
 P_404_NOT_FOUND%0A
+        
 %0A    return repl
@@ -2737,18 +2737,51 @@
  A NEW P
-ET
+RODUCT RECOMMENDATIONS RELATIONSHIP
 %0A#######
@@ -2857,19 +2857,30 @@
 route('/
-pet
+recommendation
 s', meth
@@ -2904,19 +2904,30 @@
  create_
-pet
+recommendation
 s():%0A   
@@ -2997,18 +2997,17 @@
  id = ne
-xt
+w
 _index()
@@ -3007,36 +3007,36 @@
 index()%0A        
-pets
+data
 %5Bid%5D = %7B'id': id
@@ -3063,36 +3063,58 @@
 ame'%5D, '
-kind': payload%5B'kind
+recommendations': payload%5B'recommendations
 '%5D%7D%0A    
@@ -3119,36 +3119,36 @@
       message = 
-pets
+data
 %5Bid%5D%0A        rc 
@@ -3453,32 +3453,33 @@
 ###############%0A
+%0A
 @app.route('/pet
@@ -4541,10 +4541,9 @@
 f ne
-xt
+w
 _ind
@@ -4559,30 +4559,20 @@
  global 
-current_pet_id
+data
 %0A    wit
@@ -4591,50 +4591,139 @@
     
-current_pet_id += 1%0A    return current_pet
+new_id = str(uuid.uuid4())%5B:8%5D%0A        if data.has_key(new_id):%0A            return new_index()%0A        else:%0A            return new
 _id%0A
@@ -4984,20 +4984,22 @@
         
-kind
+recomm
  = data%5B
@@ -4999,20 +4999,31 @@
 = data%5B'
-kind
+recommendations
 '%5D%0A     

add post method