
Service = require '../../../browser/model'
Entry   = require '../../../browser/model/entry'

SharePopup  = require './share-popup'

sdkReady = require './google-drive-sdk'
cache = require './cache'

class GoogleDriveService extends Service
	scope: 'https://www.googleapis.com/auth/drive.readonly'
	constructor: ->
		super
		@title = 'Google Drive'
		@type = 'image' if ~@options.types.indexOf 'image'
		@type = 'video' if ~@options.types.indexOf 'video'
		@type = 'audio' if ~@options.types.indexOf 'audio'
		@root.id = 'root'
		sdkReady.then =>
			gapi.auth2.getAuthInstance().isSignedIn.listen(@onGoglAuth)

	_auth: (interactive) => sdkReady.then =>
		return @trigger 'auth', true if gapi.auth2.getAuthInstance().isSignedIn.get()
		gapi.auth2.getAuthInstance().signIn()

	onGoglAuth: (isSignedIn) =>
		if !isSignedIn
			return @trigger 'auth', false

		@trigger 'auth', true

	refresh: (entry) =>
		@entry = entry

		onResponse = =>
			@gotResponse entry.id, arguments...

		@getDriverData entry, onResponse

	getDriverData: (entry, callback) =>
		@getDriverFolders(entry.id, callback).then =>
			@getDriverFiles(entry.id, @type, callback).then callback.bind @, [], true

	gotResponse: (folderID, data, triggerEmpty) =>
		return unless @entry.id is folderID
		self = @
		entries = (data.files or []).map (file) =>
			return unless file
			isPrivate = !file.permissions.filter((perm) -> perm.id is 'anyone' or perm.id is 'anyoneWithLink').length
			type = file.mimeType.match(/image|video|folder|audio/)[0]
			new Entry
				id: file.id
				type: type
				path: @entry.path+'/'+file.name
				name: file.name
				preview: file.thumbnailLink?.replace /s\d+$/, 's250'
				url: file.webContentLink
				parent: file.parents[0].id
				isPrivate: isPrivate
				order: 0.5*(type is 'folder') + parseFloat '0.'+(new Date(file.createdDate).getTime())
				webLink: file.webViewLink
				onActivate: ->
					return true if !@isPrivate
					SharePopup.pop $ 'body'
					SharePopup.off 'confirmed'
					SharePopup.bind 'confirmed', =>
						gapi.client.drive.permissions.create {
								resource:
									type: 'anyone',
									role: 'reader'
								fileId: file.id,
								fields: 'id',
							}
							.execute (res) =>
								if res.error
									console.error(res.error)
									alert('An error has occurred. The permissions have not been modified.')
								else
									cache.clear(file.parents[0])
									@isPrivate = false
									self.trigger 'refresh', entries, {hard: true}

					return !@isPrivate
		.filter((file)->!!(file and file.id)).sort (a, b) -> -(a.order - b.order)

		@trigger 'refresh', entries if entries.length
		@trigger 'refresh', [] if triggerEmpty and !@entry.children.length

	checkEmpty: =>
		@trigger 'refresh', []

	getURL: (entry, callback) ->
		callback entry.url

	preview: (entry)-> entry.preview

	deauth: ->
		@trigger 'auth', @authenticated = false

	getDriverFolders: (folderID, callback) =>
		@getDriverFiles folderID, 'folder', callback

	getDriverFiles: (folderID, type, callback) =>
		def = new $.Deferred

		do req = (nextPageToken = null) =>
			@requestDriverFiles(folderID, type, nextPageToken).then (resp) =>
				callback resp
				if resp.nextPageToken
					if @entry.id is folderID and entry = @entry.children.slice(-1)[0]
						entry.onShow = (-> req resp.nextPageToken; @onShow = ->).bind entry
					return
				def.resolve()

		def.promise()

	requestDriverFiles: (folderID, fileType, pageToken) =>
		def = new $.Deferred

		if cachedResponse = cache.get folderID, pageToken or fileType
			def.resolve cachedResponse

		# fetch only if cache has expired
		unless cache.check folderID, pageToken or fileType
			gapi.client.drive.files.list
				q: @createQuery folderID, fileType
				fields: 'nextPageToken, files(id, name, mimeType, thumbnailLink, createdTime, permissions, parents, webContentLink, webViewLink)'
				pageToken: pageToken
			.execute (data) =>
				delete data.result if data.result?
				cache.set folderID, pageToken or fileType, data
				def.resolve data

		def.promise()

	createQuery: (id, type, date)=>
		mimeType = "mimeType contains \'#{type}/\'"
		mimeType = 'mimeType=\'application/vnd.google-apps.folder\'' if type is 'folder'

		q = "trashed=false and (#{mimeType}) and \'#{id}\' in parents"
		q += " and modifiedDate > \'#{date}\'" if date
		q

module.exports = GoogleDriveService
