var debug = require('debug')('json-schema');

var loopback = require('loopback');
var loopbackExplorer = require('loopback-explorer');
var Model = require('loopback').Model;

var logger = require('../support/logger')

var JsonSchemaLinks = require('./json-schema-links');
var LJSRequest = require('./ljs-request');
var modelPropertiesSanitizer = require('./model-properties-sanitizer');

var JsonSchema = module.exports = Model.extend('json-schema');


JsonSchema.findByCollectionName = function(collectionName, next, callback) {
    JsonSchema.findOne({ where: { collectionName: collectionName }}, function(err, jsonSchema) {
        if (err) {
            logger.error("Error fetching JSON Schema for collectionName:", collectionName, "Error:", err);
        } else if (jsonSchema === null) {
            logger.warn("JSON Schema for collectionName", collectionName, "not found.");
        } else {
            callback(jsonSchema);
        }
        next();
    });
};


JsonSchema.prototype.defaultLinks = function(ljsReq) {
    var itemUrlTemplate = this.itemUrlTemplate(ljsReq);
    var collectionUrl = this.collectionUrl(ljsReq);
    var schemaUrl = this.url(ljsReq);
    return [
        { rel: 'self', href: itemUrlTemplate },
        { rel: 'item', href: itemUrlTemplate },
        { rel: 'create', method: 'POST', href: collectionUrl, schema: { $ref: schemaUrl } },
        { rel: 'update', method: 'PUT', href: itemUrlTemplate },
        { rel: 'delete', method: 'DELETE', href: itemUrlTemplate }
    ];
};

JsonSchema.prototype.url = function(ljsReq) {
    return ljsReq && (ljsReq.baseUrl() + '/' + this.constructor.pluralModelName + '/' + this.id);
};

JsonSchema.prototype.itemUrlTemplate = function(ljsReq) {
    return this.collectionUrl(ljsReq) + '/{id}';
};

JsonSchema.prototype.collectionUrl = function(ljsReq) {
    return ljsReq && (ljsReq.baseUrl() + '/' + this.collectionName);
};

JsonSchema.prototype.update$schema = function() {
    if (!this.$schema) {
        this.$schema = "http://json-schema.org/draft-04/hyper-schema#";
    }
};

JsonSchema.prototype.createLoopbackModel = function(app) {
    var JsonSchemaModel = JsonSchema.dataSource.createModel(this.modelName, {}, { plural: this.collectionName });
    app.model(JsonSchemaModel);
    loopbackExplorer(app);
};


JsonSchema.on('attached', function(app) {
    JsonSchema.afterRemote('**', function(ctx, result, next) {
        if (ctx.result) {
            var ljsReq = new LJSRequest(ctx.req, app);
            var defaultLinks = new JsonSchema(result).defaultLinks(ljsReq);
            var customLinks = result.links;
            var jsonSchemaLinks = new JsonSchemaLinks(ljsReq, defaultLinks, customLinks);
            ctx.result.links = jsonSchemaLinks.all();
        }
        next();
    });

    JsonSchema.afterInitialize = function() {
        modelPropertiesSanitizer.restore(this);
    }

    JsonSchema.beforeSave = function(next) {
        this.update$schema();
        modelPropertiesSanitizer.sanitize(this);
        next();
    };

    JsonSchema.afterSave = function(done) {
        this.createLoopbackModel(app);
        modelPropertiesSanitizer.restore(this);
        done();
    };
});

@@ -381,28 +381,28 @@
 zer');%0A%0Avar 
-Json
+Item
 Schema = mod
@@ -442,28 +442,28 @@
 schema');%0A%0A%0A
-Json
+Item
 Schema.findB
@@ -523,28 +523,28 @@
 back) %7B%0A    
-Json
+Item
 Schema.findO
@@ -963,28 +963,28 @@
    %7D);%0A%7D;%0A%0A%0A
-Json
+Item
 Schema.proto
@@ -1509,28 +1509,28 @@
 %0A    %5D;%0A%7D;%0A%0A
-Json
+Item
 Schema.proto
@@ -1657,28 +1657,28 @@
 is.id);%0A%7D;%0A%0A
-Json
+Item
 Schema.proto
@@ -1768,28 +1768,28 @@
 /%7Bid%7D';%0A%7D;%0A%0A
-Json
+Item
 Schema.proto
@@ -1897,28 +1897,28 @@
 nName);%0A%7D;%0A%0A
-Json
+Item
 Schema.proto
@@ -2058,20 +2058,20 @@
   %7D%0A%7D;%0A%0A
-Json
+Item
 Schema.p
@@ -2143,20 +2143,20 @@
 Model = 
-Json
+Item
 Schema.d
@@ -2295,20 +2295,20 @@
 );%0A%7D;%0A%0A%0A
-Json
+Item
 Schema.o
@@ -2337,28 +2337,28 @@
 (app) %7B%0A    
-Json
+Item
 Schema.after
@@ -2512,28 +2512,28 @@
 Links = new 
-Json
+Item
 Schema(resul
@@ -2780,28 +2780,28 @@
    %7D);%0A%0A    
-Json
+Item
 Schema.after
@@ -2881,28 +2881,28 @@
 %0A    %7D%0A%0A    
-Json
+Item
 Schema.befor
@@ -3033,20 +3033,20 @@
 %7D;%0A%0A    
-Json
+Item
 Schema.a

Rename JsonSchema -> ItemSchema.