/**
 * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */

'use strict';

( function() {
	var validLinkRegExp = /^<a[^>]+href="([^"]+)"[^>]*>([^<]+)<\/a>$/i;

	CKEDITOR.plugins.add( 'autoembed', {
		requires: 'autolink,undo',
		lang: 'ar,az,bg,ca,cs,da,de,de-ch,el,en,en-au,eo,es,es-mx,et,eu,fa,fr,gl,hr,hu,it,ja,km,ko,ku,lt,lv,mk,nb,nl,oc,pl,pt,pt-br,ro,ru,sk,sq,sr,sr-latn,sv,tr,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
		init: function( editor ) {
			var currentId = 1,
					embedCandidatePasted;

			editor.on( 'paste', function( evt ) {
				if ( evt.data.dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) {
					embedCandidatePasted = 0;
					return;
				}

				var match = evt.data.dataValue.match( validLinkRegExp );

				embedCandidatePasted = match != null && decodeURI( match[ 1 ] ) == decodeURI( match[ 2 ] );

				// Expecting exactly one <a> tag spanning the whole pasted content.
				// The tag has to have same href as content.
				if ( embedCandidatePasted ) {
					evt.data.dataValue = '<a data-cke-autoembed="' + ( ++currentId ) + '"' + evt.data.dataValue.substr( 2 );
				}
			}, null, null, 20 ); // Execute after autolink.

			editor.on( 'afterPaste', function() {
				// If one pasted an embeddable link and then undone the action, the link in the content holds the
				// data-cke-autoembed attribute and may be embedded on *any* successive paste.
				// This check ensures that autoEmbedLink is called only if afterPaste is fired *right after*
				// embeddable link got into the content. (https://dev.ckeditor.com/ticket/13532)
				if ( embedCandidatePasted ) {
					autoEmbedLink( editor, currentId );
				}
			});

			editor.on( 'instanceReady', function(evt) {
				autoEmbedLink( editor, currentId );
			});
		}
	} );

	function autoEmbedLink( editor, id ) {
		// eXo customization - begin
		// If the iframe preview already exists, we don't show a new one
		if (editor.editable().findOne( 'iframe')){
			return null;
		}

		var anchor = editor.editable().findOne( 'a[data-cke-autoembed="' + id + '"]' ) || editor.editable().findOne( 'a[id="editActivityLinkPreview"]' ),
				lang = editor.lang.autoembed;
		// eXo customization - end
		if ( !anchor || !anchor.data( 'cke-saved-href' ) ) {
			return;
		}

		var href = anchor.data( 'cke-saved-href' ),
				widgetDef = CKEDITOR.plugins.autoEmbed.getWidgetDefinition( editor, href );

		if ( !widgetDef ) {
			CKEDITOR.warn( 'autoembed-no-widget-def' );
			return;
		}

		// TODO Move this to a method in the widget plugin. https://dev.ckeditor.com/ticket/13408
		var defaults = typeof widgetDef.defaults == 'function' ? widgetDef.defaults() : widgetDef.defaults,
				element = CKEDITOR.dom.element.createFromHtml( widgetDef.template.output( defaults ) ),
				instance,
				wrapper = editor.widgets.wrapElement( element, widgetDef.name ),
				temp = new CKEDITOR.dom.documentFragment( wrapper.getDocument() );

		temp.append( wrapper );
		instance = editor.widgets.initOn( element, widgetDef );

		if ( !instance ) {
			finalizeCreation();
			return;
		}

		instance.loadContent( href, {
			noNotifications: true,
			callback: function() {
				// DOM might be invalidated in the meantime, so find the anchor again.
				// eXo customization - begin
				// get link preview anchor with id 'editActivityLinkPreview' in case of editing
				var anchor = editor.editable().findOne( 'a[data-cke-autoembed="' + id + '"]' ) || editor.editable().findOne( 'a[id="editActivityLinkPreview"]' );
				// eXo customization - end

				// Anchor might be removed in the meantime.
				if ( anchor ) {
					var selection = editor.getSelection(),
							insertRange = editor.createRange(),
							editable = editor.editable();

					// Save the changes in editor contents that happened *after* the link was pasted
					// but before it gets embedded (i.e. user pasted and typed).
					editor.fire( 'saveSnapshot' );

					// Lock snapshot so we don't make unnecessary undo steps in
					// editable.insertElement() below, which would include bookmarks. (https://dev.ckeditor.com/ticket/13429)
					editor.fire( 'lockSnapshot', { dontUpdate: true } );

					// Bookmark current selection. (https://dev.ckeditor.com/ticket/13429)
					// eXo customization - begin
					// Ignore when init edit activity ck editor
					if (editor.name.indexOf('editActivity') === -1) {
						// eXo customization - end
						var bookmark = selection.createBookmarks( false )[ 0 ],
								startNode = bookmark.startNode,
								endNode = bookmark.endNode || startNode;
					}

					// When url is pasted, IE8 sets the caret after <a> element instead of inside it.
					// So, if user hasn't changed selection, bookmark is inserted right after <a>.
					// Then, after pasting embedded content, bookmark is still in DOM but it is
					// inside the original element. After selection recreation it would end up before widget:
					// <p>A <a /><bm /></p><p>B</p>  -->  <p>A <bm /></p><widget /><p>B</p>  -->  <p>A ^</p><widget /><p>B</p>
					// We have to fix this IE8 behavior so it is the same as on other browsers.
					if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && !bookmark.endNode && startNode.equals( anchor.getNext() ) ) {
						anchor.append( startNode );
					}
					//eXo customization - begin
					// add this line for add the preview in the end of content
					var last = editable.getLast();
					insertRange.setEndAfter( last );
					// add three lines break and add close preview button
					wrapper.$.innerHTML = "<br><br><br><div style="+"'display:flex; background-color:#e1e8ee;'"+"><div style="+"width:100%"+"><br></div><div><button style="+"'cursor:pointer; border:none; background:none; color:#A8B3C5; padding:5px 8px 7px'"+">X</button></div></div>"+wrapper.$.innerHTML;
					editable.insertElement( wrapper, insertRange );
					// eXo customization - end

					// If both bookmarks are still in DOM, it means that selection was not inside
					// an anchor that got substituted. We can safely recreate that selection. (https://dev.ckeditor.com/ticket/13429)
					// eXo customization - begin
					// Ignore when init edit activity ck editor
					if (editor.name.indexOf('editActivity') === -1) {
					// eXo customization - end
						if ( editable.contains( startNode ) && editable.contains( endNode ) ) {
							selection.selectBookmarks( [ bookmark ] );
						} else {
							// If one of bookmarks is not in DOM, clean up leftovers.
							startNode.remove();
							endNode.remove();
						}
					}

					editor.fire( 'unlockSnapshot' );
					//eXo customization - begin
					//  remove the default resize button in the preview
					if (editor.editable().findOne( 'iframe')){
						editor.editable().findOne( 'span.cke_widget_drag_handler_container' ).remove();
						editor.editable().findOne( 'img' ).remove();
						var lastElement = editable.getLast();
						lastElement.remove();
						// add event of close preview button
						editor.editable().findOne( 'button' ).on( 'click', function( ev ) {
							editor.editable().findOne( 'div' ).remove();
						});

					}
					// eXo customization - end
				}

				finalizeCreation();
			},

			errorCallback: function() {
				editor.widgets.destroy( instance, true );
			}
		} );

		function finalizeCreation() {
			//eXo customization - begin
			//  remove the preview link anchor from ckeditor
			if (editor.name.indexOf('editActivity') === 0) {
				var anchor = editor.editable().findOne( 'a[id="editActivityLinkPreview"]' );
				if (anchor) {
					//get parent to remove the <p> tag added by ckeditor
					anchor.getParent().remove();
				}
			}
			// eXo customization - end
			editor.widgets.finalizeCreation( temp );
		}
	}

	CKEDITOR.plugins.autoEmbed = {
		/**
		 * Gets the definition of the widget that should be used to automatically embed the specified link.
		 *
		 * This method uses the value of the {@link CKEDITOR.config#autoEmbed_widget} option.
		 *
		 * @since 4.5.0
		 * @member CKEDITOR.plugins.autoEmbed
		 * @param {CKEDITOR.editor} editor
		 * @param {String} url The URL to be embedded.
		 * @returns {CKEDITOR.plugins.widget.definition/null} The definition of the widget to be used to embed the link.
		 */
		getWidgetDefinition: function( editor, url ) {
			var opt = editor.config.autoEmbed_widget || 'embedSemantic',
					name,
					widgets = editor.widgets.registered;

			if ( typeof opt == 'string' ) {
				opt = opt.split( ',' );

				while ( ( name = opt.shift() ) ) {
					if ( widgets[ name ] ) {
						return widgets[ name ];
					}
				}
			} else if ( typeof opt == 'function' ) {
				return widgets[ opt( url ) ];
			}

			return null;
		}
	};

	/**
	 * Specifies the widget to use to automatically embed a link. The default value
	 * of this option defines that either the [Media Embed](https://ckeditor.com/cke4/addon/embed) or
	 * [Semantic Media Embed](https://ckeditor.com/cke4/addon/embedsemantic) widgets will be used, depending on which is enabled.
	 *
	 * The general behavior:
	 *
	 * * If a string (widget names separated by commas) is provided, then the first of the listed widgets which is registered
	 *   will be used. For example, if `'foo,bar,bom'` is set and widgets `'bar'` and `'bom'` are registered, then `'bar'`
	 *   will be used.
	 * * If a callback is specified, then it will be executed with the URL to be embedded and it should return the
	 *   name of the widget to be used. It allows to use different embed widgets for different URLs.
	 *
	 * Example:
	 *
	 * ```js
	 * // Defines that embedSemantic should be used (regardless of whether embed is defined).
	 * config.autoEmbed_widget = 'embedSemantic';
	 * ```
	 *
	 * Using with custom embed widgets:
	 *
	 * ```js
	 * config.autoEmbed_widget = 'customEmbed';
	 * ```
	 *
	 * **Note:** Plugin names are always lower case, while widget names are not, so widget names do not have to equal plugin names.
	 * For example, there is the `embedsemantic` plugin and the `embedSemantic` widget.
	 *
	 * Read more in the {@glink features/media_embed#automatic-embedding-on-paste documentation}
	 * and see the {@glink examples/mediaembed example}.
	 *
	 * @since 4.5.0
	 * @cfg {String/Function} [autoEmbed_widget='embed,embedSemantic']
	 * @member CKEDITOR.config
	 */
} )();
