import Account from "../domain/Account";
import AccountRepository from "../domain/AccountRepository";
import Authorization from "../domain/Authorization";
import AccountSchema from "./AccountSchema";

export default class AccountRepositoryMongo implements AccountRepository {

    public addAccount(account: Account): Promise<string> {
        return AccountSchema.create({
                username: account.username,
                hash: [...account.hash.values()],
                salt: [...account.salt.values()],
                authorizationSet: account.authorizationSet.map( (authorization) => {
                    return {
                        kind: authorization.kind,
                        key: authorization.key,
                    };
                }),
            })
            .then( (document) => {
                return account.username;
            });
    }

    public updateAccount(account: Account): Promise<string> {
        const username = account.username;
        const authorizationSet = account.authorizationSet.map( (authorization) => {
            return {
                kind: authorization.kind,
                key: authorization.key,
            };
        });
        return AccountSchema.updateOne({username}, {$set: {authorizationSet}})
            .exec()
            .then( () => {
                return account.username;
            });
    }

    public findAccountByUserName(username: string): Promise<Account> {
        return AccountSchema.findOne({username}).lean().exec()
            .then((accountDocument: any) => {
                if (!accountDocument) {
                    return null;
                }
                const account = new Account(username, Uint8Array.from(accountDocument.salt), Uint8Array.from(accountDocument.hash));
                accountDocument.authorizationSet.forEach((authorizationDoc) => {
                    const authorization = new Authorization(parseInt(authorizationDoc.kind), authorizationDoc.key);
                    account.addAuthorization(authorization);
                });
                return account;
            });
    }

}
