import CommanderCommand   from '../../CommanderCommand';
import chalk              from 'chalk';
import ora                from 'ora';
import GitlabManager      from '../../../managers/GitlabManager';
import GitlabUser         from '../../../shared/types/Gitlab/GitlabUser';
import DojoBackendManager from '../../../managers/DojoBackendManager';
import Toolbox            from '../../../shared/helpers/Toolbox';
import AccessesHelper     from '../../../helpers/AccessesHelper';
import Assignment         from '../../../sharedByClients/models/Assignment';


class AssignmentCreateCommand extends CommanderCommand {
    protected commandName: string = 'create';

    protected defineCommand() {
        this.command
        .description('create a new repository for an assignment')
        .requiredOption('-n, --name <name>', 'name of the assignment')
        .option('-i, --members_id <ids...>', 'list of gitlab members ids (teaching staff) to add to the repository')
        .option('-u, --members_username <usernames...>', 'list of gitlab members username (teaching staff) to add to the repository')
        .option('-t, --template <string>', 'id or url of the template (http/s and ssh urls are possible)')
        .action(this.commandAction.bind(this));
    }

    protected async commandAction(options: any): Promise<void> {
        let members!: Array<GitlabUser> | false;
        let templateIdOrNamespace: string | null = null;

        // Check access and retrieve data
        {
            console.log(chalk.cyan('Please wait while we verify and retrieve data...'));

            if ( !await AccessesHelper.checkTeachingStaff() ) {
                return;
            }

            members = await GitlabManager.fetchMembers(options);
            if ( !members ) {
                return;
            }

            const assignmentGetSpinner: ora.Ora = ora('Checking assignment name availability').start();
            if ( await DojoBackendManager.getAssignment(options.name) ) {
                assignmentGetSpinner.fail(`Assignment name "${ options.name }" is already taken. Please choose another one.`);
                return;
            }
            assignmentGetSpinner.succeed(`Assignment name "${ options.name }" is available`);

            if ( options.template ) {
                templateIdOrNamespace = options.template;

                if ( Number.isNaN(Number(templateIdOrNamespace)) ) {
                    templateIdOrNamespace = Toolbox.urlToPath(templateIdOrNamespace as string);
                }

                if ( !await DojoBackendManager.checkTemplateAccess(encodeURIComponent(templateIdOrNamespace as string)) ) {
                    return;
                }
            }
        }

        // Create the assignment
        {
            console.log(chalk.cyan('Please wait while we are creating the assignment...'));

            try {
                const assignment: Assignment = await DojoBackendManager.createAssignment(options.name, members, templateIdOrNamespace);

                const oraInfo = (message: string) => {
                    ora({
                            text: message, indent: 4
                        }).start().info();
                };

                oraInfo(`${ chalk.magenta('Name:') } ${ assignment.name }`);
                oraInfo(`${ chalk.magenta('Web URL:') } ${ assignment.gitlabCreationInfo.web_url }`);
                oraInfo(`${ chalk.magenta('HTTP Repo:') } ${ assignment.gitlabCreationInfo.http_url_to_repo }`);
                oraInfo(`${ chalk.magenta('SSH Repo:') } ${ assignment.gitlabCreationInfo.ssh_url_to_repo }`);
            } catch ( error ) {
                return;
            }
        }
    }
}


export default new AssignmentCreateCommand();