const models = require('../');
const Job = models.Job;
const User = models.User;
const Project = models.Project;
const async = require('async');
const utils = require('../../utils');
module.exports = function (done) {
    upgradeUsers(function (err) {
        if (err)
            return done(err);
        upgradeJobs(done);
    });
};
function upgradeJobs(done) {
    Job.collection.find({}, function (err, cursor) {
        if (err)
            return done(err);
        cursor.toArray(function (err, jobs) {
            if (err)
                return done(err);
            console.log('converting', jobs.length, 'jobs');
            const tasks = [];
            jobs.forEach(function (job) {
                tasks.push(function (next) {
                    upgradeJob(job, next);
                });
            });
            async.series(tasks, done);
        });
    });
}
function upgradeJob(job, done) {
    Job.findById(job._id)
        .lean()
        .exec(function (err, mjob) {
        if (err)
            return done(err);
        mjob.user_id = job._owner;
        mjob.project = makeName(job.repo_url);
        mjob.ref = {
            branch: 'master',
        };
        if (job.github_commit_info) {
            mjob.ref.id = job.github_commit_info.id;
        }
        mjob.std = {
            out: job.stdout || '',
            err: job.stderr || '',
            merged: job.stdmerged || '',
        };
        mjob.created = job.created_timestamp;
        mjob.finished = job.finished_timestamp;
        mjob.queued = mjob.created;
        mjob.started = mjob.created;
        mjob.duration = mjob.finished
            ? mjob.finished.getTime() - mjob.created.getTime()
            : 0;
        mjob.archived = job.archived_timestamp;
        mjob.trigger = makeTrigger(job, job.github_commit_info);
        mjob.plugin_data = {};
        if (job.tasks && job.tasks.length) {
            mjob.plugin_data.sauce = job.tasks;
        }
        killAttrs(mjob, [
            'created_timestamp',
            'finished_timestamp',
            'archived_timestamp',
            '_owner',
            'repo_url',
            'stdout',
            'stderr',
            'stdmerged',
            'tasks',
        ]);
        mjob.phases = {
            environment: {
                commands: [],
            },
            prepare: {
                commands: [],
            },
            test: {
                finished: mjob.finished,
                duration: mjob.duration,
                exitCode: mjob.test_exitcode,
                commands: [
                    {
                        started: mjob.started,
                        duration: mjob.duration,
                        command: 'Legacy job output',
                        out: mjob.std.out,
                        err: mjob.std.err,
                        merged: mjob.std.merged,
                    },
                ],
            },
            deploy: {
                commands: [],
            },
            cleanup: {
                commands: [],
            },
        };
        Job.collection.updateOne({ _id: job._id }, mjob, done);
        console.log('done job', job._id);
    });
}
function makeTrigger(job, commit) {
    if (!commit) {
        return {
            type: 'manual',
            author: {
                id: job._owner,
            },
            message: job.type === 'TEST_AND_DEPLOY' ? 'Redeploy' : 'Retest',
            timestamp: job.created_timestamp,
            source: { type: 'UI', page: 'Unknown' },
        };
    }
    commit.author.image = utils.gravatar(commit.author.email);
    return {
        type: 'commit',
        author: commit.author,
        message: commit.message,
        timestamp: commit.timestamp,
        url: `${job.repo_url}/commit/${commit.id}`,
        source: { type: 'plugin', plugin: 'github' },
    };
}
function upgradeUsers(done) {
    User.collection.find({}, function (err, cursor) {
        if (err)
            return done(err);
        cursor.toArray(function (err, users) {
            if (err)
                return done(err);
            console.log('converting users', users.length);
            const tasks = [];
            users.forEach(function (user) {
                tasks.push(function (next) {
                    upgradeUser(user, next);
                });
            });
            async.series(tasks, done);
        });
    });
}
function makeGithubRepos(user) {
    if (!user.github)
        return [];
    const github = user.github_metadata[user.github.id].repos;
    const repos = [];
    for (let i = 0; i < github.length; i++) {
        repos.push({
            id: `${github[i].id}`,
            name: github[i].full_name && github[i].full_name.toLowerCase(),
            display_name: github[i].full_name,
            group: github[i].owner.login,
            display_url: github[i].html_url,
            config: {
                url: `git://${github[i].clone_url.split('//')[1]}`,
                owner: github[i].owner.login,
                repo: github[i].name,
                auth: {
                    type: 'https',
                },
            },
        });
    }
    return repos;
}
// remove attributes from a model
function killAttrs(model, attrs) {
    for (let i = 0; i < attrs.length; i++) {
        delete model[attrs[i]];
    }
}
function makeHerokuAccounts(user) {
    if (!user.heroku || !user.heroku.length)
        return { accounts: [], apps: {} };
    const keys = {};
    const accounts = [];
    const caches = {};
    const apps = {};
    user.heroku.forEach(function (account) {
        let aid = account.account_id.split('@')[0];
        if (keys[account.api_key]) {
            aid = keys[account.api_key];
        }
        else {
            caches[account.api_key] = [];
        }
        apps[account.account_id] = {
            id: account.account_id.split('@')[0].split('-')[1],
            name: account.app,
            account: aid,
            git_url: `git@heroku.com:${account.app}.git`,
            web_url: `http://${account.app}.herokuapp.com/`,
        };
        caches[account.api_key].push(apps[account.account_id]);
        if (keys[account.api_key]) {
            return;
        }
        keys[account.api_key] = aid;
        accounts.push({
            id: aid,
            api_key: account.api_key,
            email: aid,
            privkey: account.privkey,
            pubkey: account.pubkey,
            cache: caches[account.api_key],
        });
    });
    return {
        accounts: accounts,
        apps: apps,
    };
}
function upgradeUser(user, done) {
    User.findById(user._id)
        .lean()
        .exec(function (err, mongUser) {
        const heroku = makeHerokuAccounts(user);
        mongUser.accounts = [];
        if (user.github && user.github.id) {
            mongUser.accounts.push({
                provider: 'github',
                id: user.github.id,
                display_url: `https://github.com/${user.github.login}`,
                title: user.github.login,
                config: convertGithub(user),
                cache: makeGithubRepos(user),
            });
        }
        mongUser.jobplugins = {
            heroku: {
                accounts: heroku.accounts,
            },
        };
        mongUser.projects = [];
        killAttrs(mongUser, [
            'github',
            'github_config',
            'github_metadata',
            'dotcloud_config',
            'heroku',
        ]);
        const projects = [];
        if (user.github_config && user.github_config.length > 0) {
            for (let i = 0; i < user.github_config.length; i++) {
                const repo_config = user.github_config[i];
                const name = makeName(repo_config.display_url);
                mongUser.projects.push({
                    name: name.toLowerCase(),
                    display_name: name,
                    access_level: 2,
                });
                projects.push(makeProject(name, repo_config, user, heroku));
            }
        }
        Project.create(projects, function (err) {
            if (err)
                return done(err);
            User.collection.updateOne({ _id: mongUser._id }, mongUser, done);
        });
        console.log('projects', projects.length, user._id);
    });
}
function makeName(url) {
    return url.split('/').slice(-2).join('/').split('.')[0];
}
function makeProvider(name, repo, user) {
    // TODO: how do I know if it's not github?
    const parts = name.split('/');
    const repos = user.github_metadata[user.github.id].repos;
    let url = `git://${repo.display_url.split('//')[1]}.git`;
    let id = null;
    for (let i = 0; i < repos.length; i++) {
        if (repos[i].html_url === repo.display_url) {
            id = repos[i].id;
            url = `git://${repos[i].git_url.split('//')[1]}`;
            break;
        }
    }
    return {
        id: 'github',
        repo_id: id,
        account: user.github.id,
        config: {
            url: url,
            owner: parts[0],
            repo: parts[1],
            auth: {
                type: 'https',
            },
        },
    };
}
// plugins that we need:
// node
//
// Optional:
// browserstack
// webhooks
// heroku
// custom
// env
// jelly
// qunit
// sauce
const checkPlugins = {
    sauce: function (repo) {
        if (!repo.sauce_access_key)
            return;
        return {
            access_key: repo.sauce_access_key,
            username: repo.sauce_username,
            browsers: repo.sauce_browsers,
        };
    },
    qunit: function (repo) {
        if (!repo.qunit_file)
            return;
        return {
            file: repo.qunit_file,
            path: repo.qunit_path,
        };
    },
    jelly: function (repo) {
        if (!repo.jelly_payload)
            return;
        return {
            url: repo.jelly_url,
            port: repo.jelly_port,
            payload: repo.jelly_payload,
            static: repo.jelly_static,
            static_dir: repo.jelly_static_dir,
        };
    },
    env: function (repo) {
        return repo.env;
    },
    custom: function (repo) {
        return repo.custom;
    },
    heroku: function (repo, user, heroku) {
        if (!repo.prod_deploy_target ||
            repo.prod_deploy_target.provider !== 'heroku')
            return;
        const account_id = repo.prod_deploy_target.account_id;
        return { app: heroku.apps[account_id] };
    },
    webhooks: function (repo) {
        if (!repo.webhooks || !repo.webhooks.length)
            return;
        const hooks = [];
        let hook;
        for (let i = 0; i < repo.webhooks.length; i++) {
            hook = repo.webhooks[i];
            hooks.push({
                id: hook._id,
                url: hook.url,
                secret: hook.secret,
                format: '',
                trigger: 'job.done',
            });
        }
        return hooks;
    },
    browserstack: function (repo) {
        if (!repo.browserstack_api_key)
            return;
        return {
            apiKey: repo.browserstack_api_key,
            username: repo.browserstack_username,
            password: repo.browserstack_password,
            browsers: repo.browserstack_browsers,
        };
    },
};
function makePlugins(repo, user, heroku) {
    const plugins = [
        {
            id: 'node',
            enabled: true,
            config: {
                test: 'npm install',
                runtime: 'whatever',
            },
        },
    ];
    Object.keys(checkPlugins).forEach(function (name) {
        const config = checkPlugins[name](repo, user, heroku);
        if (!config)
            return;
        plugins.push({
            id: name,
            enabled: true,
            config: config,
        });
    });
    return plugins;
}
function makeBranch(repo, user, heroku) {
    return {
        active: repo.active,
        name: 'master',
        mirror_master: false,
        deploy_on_green: repo.prod_deploy_target && repo.prod_deploy_target.deploy_on_green,
        deploy_on_pull_request: false,
        pubkey: repo.pubkey,
        privkey: repo.privkey,
        plugins: makePlugins(repo, user, heroku),
        plugin_data: {},
        runner: {
            id: 'simple-runner',
            config: {
                pty: false,
            },
        },
    };
}
function makeProject(name, repo, user, heroku) {
    return {
        name: name.toLowerCase(),
        secret: repo.secret,
        public: repo.public,
        display_name: name,
        display_url: repo.display_url,
        creator: user._id,
        branches: [makeBranch(repo, user, heroku)],
        provider: makeProvider(name, repo, user),
    };
}
function convertGithub(user) {
    if (!user.github)
        return {};
    const g = user.github;
    return {
        accessToken: g.accessToken,
        login: g.login,
        email: g.email,
        gravatarId: g.gravatarId,
        name: g.name,
    };
}
//# sourceMappingURL=from0to1.js.map