/**
 * boot
 */

const riot = require('riot');
require('velocity-animate');
const api = require('./common/scripts/api.ls');
const signout = require('./common/scripts/signout.ls');
const generateDefaultUserdata = require('./common/scripts/generate-default-userdata.ls');
const mixins = require('./common/mixins.ls');
const checkForUpdate = require('./common/scripts/check-for-update.ls');
require('./common/tags');

/**
 * MISSKEY ENTORY POINT!
 */

document.domain = CONFIG.host;

// ↓ iOS待ちPolyfill (SEE: http://caniuse.com/#feat=fetch)
require('whatwg-fetch');

// ↓ NodeList、HTMLCollectionで forEach を使えるようにする
if (NodeList.prototype.forEach === undefined) {
	NodeList.prototype.forEach = Array.prototype.forEach;
}
if (HTMLCollection.prototype.forEach === undefined) {
	HTMLCollection.prototype.forEach = Array.prototype.forEach;
}

// ↓ iOSでプライベートモードだとlocalStorageが使えないので既存のメソッドを上書きする
try {
	localStorage.setItem('kyoppie', 'yuppie');
} catch (e) {
	Storage.prototype.setItem = () => { }; // noop
}

// Check for Update
checkForUpdate();

// Get token from cookie
const i = (document.cookie.match(/i=(!\w+)/) || [null, null])[1];

// ユーザーをフェッチしてコールバックする
module.exports = callback => {
	// Get cached account data
	let cachedMe = JSON.parse(localStorage.getItem('me'));

	if (cachedMe != null && cachedMe.data != null && cachedMe.data.cache) {
		fetched(cachedMe);

		// 後から新鮮なデータをフェッチ
		fetchme(i, true, freshData => {
			Object.assign(cachedMe, freshData);
			cachedMe.trigger('updated');
		});
	} else {
		// キャッシュ無効なのにキャッシュが残ってたら掃除
		if (cachedMe != null) {
			localStorage.removeItem('me');
		}

		fetchme(i, false, fetched);
	}

	function fetched(me) {
		if (me != null) {
			riot.observable(me);

			me.update = data => {
				if (data) Object.assign(me, data);
				me.trigger('updated');
			};

			if (me.data.cache) {
				localStorage.setItem('me', JSON.stringify(me));

				me.on('updated', () => {
					// キャッシュ更新
					localStorage.setItem('me', JSON.stringify(me));
				});
			}
		}

		mixins(me);

		const init = document.getElementById('init');
		init.parentNode.removeChild(init);

		const app = document.createElement('div');
		app.setAttribute('id', 'app');
		document.body.appendChild(app);

		try {
			callback(me);
		} catch (e) {
			panic(e);
		}
	}
};

// ユーザーをフェッチしてコールバックする
function fetchme(token, silent, cb) {
	let me = null;

	// Return when not signed in
	if (token == null) {
		return done();
	}

	// Fetch user
	fetch(CONFIG.api.url + "/i", {
		method: 'POST',
		headers: {
			'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
		},
		body: "i=" + token
	}).then(res => {
		// When failed to authenticate user
		if (res.status !== 200) {
			return signout();
		}

		res.json().then(i => {
			me = i;
			me.token = token;

			// initialize it if user data is empty
			if (me.data != null) {
				done();
			} else {
				init();
			}
		});
	}).catch(() => {
		if (!silent) {
			const info = document.body.appendChild(document.createElement('mk-core-error'));
			riot.mount(info, {
				retry: () => {
					fetchme(token, false, cb);
				}
			});
		}
	});

	function done() {
		if (cb != null) {
			cb(me);
		}
	}

	function init() {
		const data = generateDefaultUserdata();
		api(token, 'i/appdata/set', {
			data: JSON.stringify(data)
		}).then(() => {
			me.data = data;
			done();
		});
	}
}

function panic(e) {
	console.error(e);
	document.body.innerHTML = '<div id="error"><p>致命的な問題が発生しました。</p></div>';
}

@@ -1039,100 +1039,8 @@
 );%0A%0A
-// Get token from cookie%0Aconst i = (document.cookie.match(/i=(!%5Cw+)/) %7C%7C %5Bnull, null%5D)%5B1%5D;%0A%0A
 // %E3%83%A6
@@ -1058,16 +1058,16 @@
 %E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF%E3%81%99%E3%82%8B%0A
+
 module.e
@@ -1303,15 +1303,22 @@
 hme(
-i, true
+cachedMe.token
 , fr
@@ -1513,16 +1513,112 @@
 %0A%09%09%7D%0A%0A%09%09
+// Get token from cookie%0A%09%09const i = (document.cookie.match(/i=(!%5Cw+)/) %7C%7C %5Bnull, null%5D)%5B1%5D;%0A%0A%09%09
 fetchme(
@@ -1618,23 +1618,16 @@
 etchme(i
-, false
 , fetche
@@ -2323,16 +2323,8 @@
 ken,
- silent,
  cb)
@@ -2879,24 +2879,18 @@
 ;%0A%09%7D
-).catch(
+, 
 () =%3E %7B%0A
 %09%09if
@@ -2889,26 +2889,8 @@
 %3E %7B%0A
-%09%09if (!silent) %7B%0A%09
 %09%09co
@@ -2970,17 +2970,16 @@
 r'));%0A%09%09
-%09
 riot.mou
@@ -2992,17 +2992,16 @@
 o, %7B%0A%09%09%09
-%09
 retry: (
@@ -3003,25 +3003,24 @@
 ry: () =%3E %7B%0A
-%09
 %09%09%09%09fetchme(
@@ -3029,38 +3029,25 @@
 ken,
- false,
  cb);%0A
-%09
 %09%09%09%7D%0A%09%09
-%09
 %7D);%0A
-%09%09%7D%0A
 %09%7D);

Fix bug