import ghostPaths from 'ghost-admin/utils/ghost-paths';

import mockApiKeys from './config/api-keys';
import mockAuthentication from './config/authentication';
import mockConfig from './config/config';
import mockEmailPreview from './config/email-preview';
import mockEmails from './config/emails';
import mockIntegrations from './config/integrations';
import mockInvites from './config/invites';
import mockLabels from './config/labels';
import mockMembers from './config/members';
import mockMentions from './config/mentions';
import mockNewsletters from './config/newsletters';
import mockOffers from './config/offers';
import mockPages from './config/pages';
import mockPosts from './config/posts';
import mockRoles from './config/roles';
import mockSearchIndex from './config/search-index';
import mockSettings from './config/settings';
import mockSite from './config/site';
import mockSlugs from './config/slugs';
import mockSnippets from './config/snippets';
import mockStats from './config/stats';
import mockTags from './config/tags';
import mockThemes from './config/themes';
import mockTiers from './config/tiers';
import mockUploads from './config/uploads';
import mockUsers from './config/users';
import mockWebhooks from './config/webhooks';

/* eslint-disable ghost/ember/no-test-import-export */
export default function () {
    this.namespace = ghostPaths().apiRoot;
    // this.timing = 400;      // delay for each request, automatically set to 0 during testing
    this.logging = false;

    mockApiKeys(this);
    mockAuthentication(this);
    mockConfig(this);
    mockEmailPreview(this);
    mockEmails(this);
    mockIntegrations(this);
    mockInvites(this);
    mockMembers(this);
    mockLabels(this);
    mockPages(this);
    mockPosts(this);
    mockRoles(this);
    mockSearchIndex(this);
    mockSettings(this);
    mockSite(this);
    mockSlugs(this);
    mockTags(this);
    mockThemes(this);
    mockUploads(this);
    mockUsers(this);
    mockWebhooks(this);
    mockTiers(this);
    mockOffers(this);
    mockSnippets(this);
    mockNewsletters(this);
    mockStats(this);
    mockMentions(this);

    /* Notifications -------------------------------------------------------- */

    this.get('/notifications/');

    /* Integrations - Slack Test Notification ------------------------------- */

    this.post('/slack/test', function () {
        return {};
    });

    /* Delete all ----------------------------------------------------------- */

    this.del('/db', function (db) {
        db.posts.all().remove();
        db.tags.all().remove();
    }, 204);

    /* limit=all blocker ---------------------------------------------------- */
    const originalHandledRequest = this.pretender.handledRequest;
    this.pretender.handledRequest = function (verb, path, request) {
        originalHandledRequest.call(this, verb, path, request);

        const url = new URL(request.url, window.location.origin);
        const limit = url.searchParams.get('limit');

        const ALLOWED_LIMIT_ALL = [
            '/api/admin/members/upload/'
        ];

        // limit=all is completely blocked, we shouldn't have any requests reach the server with this
        if (limit === 'all' && !ALLOWED_LIMIT_ALL.some(allowed => path.includes(allowed))) {
            throw new Error(`Blocked mirage request with limit=all: ${verb} ${path}.`);
        }

        // limit > 100 is also blocked, apart from some specific endpoints
        if (limit && parseInt(limit, 10) > 100) {
            const parsedLimit = parseInt(limit, 10);

            const SEARCH_ENDPOINTS_REGEX = /\/api\/admin\/(posts|pages|tags|users)\//;
            if (parsedLimit === 10000 && SEARCH_ENDPOINTS_REGEX.test(path)) {
                return;
            }

            if (path.match(/\/emails\/.*\/batches\//)) {
                return;
            }

            if (path.includes('/api/admin/posts/export/')) {
                return;
            }

            throw new Error(`Blocked mirage request with limit > 100: ${verb} ${path}.`);
        }
    };

    /* External sites ------------------------------------------------------- */

    this.head('http://www.gravatar.com/avatar/:md5', function () {
        return '';
    }, 200);

    this.get('http://www.gravatar.com/avatar/:md5', function () {
        return '';
    }, 200);

    this.get('https://ghost.org/changelog.json', function () {
        return {
            posts: [
                {
                    title: 'Custom image alt tags',
                    custom_excerpt: 'Alt tag support for images in the Ghost editor',
                    slug: 'image-alt-text-support',
                    published_at: '2019-08-05T07:46:16.000+00:00',
                    url: 'https://ghost.org/changelog/image-alt-text-support/',
                    featured: 'false'
                }
            ],
            changelogUrl: 'https://ghost.org/changelog/'
        };
    });
}
