# Source: themes/ess-dive/views/MetadataView.js

    /*global define */
    define(['jquery',
    		'underscore',
    		'views/BaseMetadataView',
    		'models/DataONEObject'
    		],
    	function($, _,BaseMetadataView, DataONEObject) {
            'use strict';

            var MetadataView = BaseMetadataView.extend({

    			/** EXTEND ancestor
    			 * EXTEND NOTES: Don't execute the function if null is passed in for json. We want to do this
    			 * because we changed overrode generateJSONLD to not return the JSONLD but to update the model in the
    			 * done callback.
    			 *
    			 *  ------------- Ancestor Doc ---------------
    			 * Insert Schema.org-compliant JSONLD for the model bound to the view into
    			 * the head tag of the page (at the end).
    			 *
    			 * @param {object} json - JSON-LD to insert into the page
    			 *
    			 * Some notes:
    			 *
    			 * - Checks if the JSONLD already exists from the previous data view
    			 * - If not create a new script tag and append otherwise replace the text
    			 *   for the script
    			 */
    			insertJSONLD: function(json){
    				if (json) {
    					BaseMetadataView.prototype.insertJSONLD.apply(this, [json]);
    				}
    			},

    			/** OVERRIDE Ancestor
    			 * OVERRIDE NOTES: This overrides the ancestor function by using the
    			 * ESS-DIVE custom json-ld metacat view service. This method is making
    			 * and asynchronous call to the json-ld view service and is updating vhew
    			 * MetadataView model receiving the response
    			 *
    			 * ------ Ancestor Doc -----------
    			 * Generate Schema.org-compliant JSONLD for the model bound to the view into
    			 *  the head tag of the page by `insertJSONLD`.
    			 *
    			 * Note: `insertJSONLD` should be called to do the actual inserting into the
    			 * DOM.
    			 */
    			generateJSONLD: function () {

    				// Reference this so that we can access it in the ajax callback
    				var thisView = this;

    				// Build the JSONLD view service endpoint.
    				var jsonldEndpoint = MetacatUI.appModel.get('baseUrl') +
    					 MetacatUI.appModel.get('context') + MetacatUI.appModel.get('d1Service') + '/views/json-ld/'+
    					this.model.get("id");

    				// Default JSON is empty.
    				var json_ld='{}';

    				// Call the JSON-LD view service asynchronously
    				$.ajax({
    					url: jsonldEndpoint,
    					type: "GET",
    					headers: {
    						"Authorization": "Bearer " + MetacatUI.appUserModel.get("token")},
    					contentType: "application/json"
    				}).done(function( result ) {
    					// Update the JSON_LD Model in the Metadata View page
    					// This is an asynchronous call and the json result
    					// may not be available by the time we hit the
    					// end of this method
    					thisView.insertJSONLD(JSON.parse(result));
    				});

    				// The view model is being updated in this function. Otherwise we would
    				// have to make the above call synchronously.
    				return null
    			},

    			/**
    			 * Shows the confirmation message on successful save
    			 *
    			 * @param model
    			 * @param value
                 * @param options
                 */
    			handleSaveMetadata: function(model, value, options){
    				var msg = "Your publication request "
    					+ "has been received. An ESS-DIVE admin will check the submission and contact you "
    					+ "through the email address in your profile. Note that the publication status will "
    					+ "not prevent you from editing your data package. The data package will not be published "
    					+ "until you respond to our email and address all issues regarding your submission.";
    				this.$el.find("div.alert").remove()
    				this.$el.find('.container').prepend(
    				this.alertTemplate({
    					msg: msg,
    					classes: 'alert-success'
    				})
    				);

    			},
    			/**
    			 * Shows confirmation message that the dataset DOI has already been requested
    			 *
    			 * @param model
    			 * @param value
                 * @param options
                 */
    			handleAlreadyRequested: function(model, value, options){
    				var msg = "You have already requested to publish this data package. "
    					+"Contact "+MetacatUI.appModel.get("emailContact") + " if you have any questions.";
    				this.$el.find("div.alert").remove()
    				this.$el.find('.container').prepend(
    				this.alertTemplate({
    					msg: msg,
    					classes: 'alert-warning'
    				})
    				);

    			},
    			/***
    			 * Handle error on fetch
    			 *
    			 * @param model
                 * @param viewRef
                 */
    			handleError: function(model, viewRef){
    				// show the error message, but stay on the same page
    				var msg = "Publish failed: " + $(response.responseText).find("description").text();

    				viewRef.hideLoading();
    				viewRef.showError(msg);

    			},
    			/**
    			 * Adds Allow write access to the specified subject and access policy
    			 *
    			 * @param subject - subject to give write access to
    			 * @param model - the model whose access policy is to be  modified
                 * @returns {object} returns new access policy if the given access policy was updated
                 */
    			addAllowWriteAccess: function(subject, model){
    				// Create the access policy for the given subject
    				var share_access_policy = {
    						subject: subject,
    						read: true
    					};

    				// get the access policy from the model
    				var accessPolicy = model.get("accessPolicy");

    				// Now inspect the access policy to see if
    				// thes subject has already been given write access.
    				if (!accessPolicy || accessPolicy.length == 0 ){
    					// No access policy
    					return [share_access_policy];
    				}
    				else if (accessPolicy.length >=0) {
    					 // There is one but lets see if the subject has read
    					 var alreadyRequested = accessPolicy.any(
    						 function(policy){ return policy.get("subject") == subject; },
    						 subject);

    					 // Did they already request to be published
    					 if (alreadyRequested ) return null;

    					 // Give the subject write access
    					 accessPolicy.push(share_access_policy);
    					 return accessPolicy
    				}
    				else {
    					// This is a special case where accessPolicy.allow is not an array
    					if (accessPolicy.read == true && accessPolicy.subject == subject) return null;
    					return  {
    						subject: share_access_policy,
    						read: true
    					};
    				}
    			},
                /**
                 * Override the publish function the mark a dataset for publishing.
                 *
                 * @param event
                 */
                publish: function(event){
                    // target may not actually prevent click events, so double check
                    var disabled = $(event.target).closest("a").attr("disabled");
                    if (disabled) {
                        return false;
                    }
                    var pid = $(event.target).closest("a").attr("pid");
                    var ret = confirm("Are you sure you want to publish? Publishing the data " +
    					"package will make it publicly available for search and download." +
    					"\n\nThe data package will be published with an existing DOI, if you supplied one, or " +
    					"else a new DOI will be issued through ESS-DIVE." +
    					"\n\nIf you click \"OK\", this data package will be put into a publication queue. " +
    					"An ESS-DIVE admin will check the submission and contact you through the email address in your profile. " +
    					"Note that the publication status will not prevent you from editing your data package. " +
    					"The data package will not be published until you respond to our email " +
    					"and address all issues regarding your submission.");

                    if (ret) {

    					// DataONEObject.save expects this to be in the
    					// global rootDataPackage
                        MetacatUI.rootDataPackage = this.dataPackage;

    					// Fetch the metadata model from the archive
    				    var viewRef = this;
    					var metadataModel = new DataONEObject({id: this.pid, sync:true});
                    	metadataModel.fetch( {
    						success: function(model, response, options){
    							// We have the model let's see if they already request access
    							var accessPolicy = viewRef.addAllowWriteAccess(MetacatUI.appModel.get("shareGroup"), model);
    							if (accessPolicy) {
    								// This is the first time they have requested access
    								// update the metadata model with a new access policy
    								model.once("successSaving", viewRef.handleSaveMetadata, viewRef);
    								model.set("accessPolicy", accessPolicy);
    								model.save({accessPolicy: accessPolicy});
    							}
    							else{
    								viewRef.handleAlreadyRequested(model,response, options);
    							}
    						}
    						,
    						error: function(model, response, options){
    							viewRef.handleError(model, viewRef)}
    					}
    					);

                    }
                }

            });

            return MetadataView

        }
    );