import { Injectable } from '@nestjs/common';
import { UserDTO } from 'src/common/dto/user-dto';
import { checkProjectAccess } from 'src/utils/project-access';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ProjectEntity } from '../entities/project.entity';
import { ApiError } from '../common/error/api-error';
import { ApiErrorCodes } from '../common/error/api-error-codes';

@Injectable()
export class FileService {
  constructor(
    @InjectRepository(ProjectEntity)
    private readonly projectRepo: Repository<ProjectEntity>,
    private readonly jwtService: JwtService,
    private readonly configService: ConfigService,
  ) {}

  async getFileToken(account: UserDTO, store: string): Promise<string> {
    let maxSize: number;
    let quota: number;
    let rights = 'r';

    const project_store = store.match(/^p-(.+)$/);
    const account_store = store.match(/^u-(.+)$/);
    if (project_store) {
      const projectId = project_store[1];
      const project_access = await checkProjectAccess(
        this.projectRepo.manager.connection,
        account.id,
        projectId,
      );

      maxSize = this.configService.get('file.maxSizeFreeProject');
      quota = this.configService.get('file.quotaFreeProject');
      if (project_access.projectLicense) {
        maxSize = project_access.projectLicense.features.fsMaxFileSize;
        quota = project_access.projectLicense.features.fsStorageSize;
      }
      if (project_access.userRole) {
        rights = 'rw';
      }
    } else if (account_store) {
      const account_id = parseInt(account_store[1]);
      maxSize = this.configService.get('file.maxSizeAccount');
      quota = this.configService.get('file.quotaAccount');
      if (account_id === account.id) {
        rights = 'rw';
      }
    } else throw new ApiError('Invalid store', ApiErrorCodes.PARAM_BAD_VALUE);

    if (rights === 'r') {
      maxSize = 0;
      quota = 0;
    }

    return this.jwtService.sign(
      {
        user: account.id.toString(),
        store: store,
        access: [
          {
            dir: null,
            maxSize,
            quota,
            rights,
          },
        ],
      },
      {
        expiresIn: '60s',
        subject: account.id.toString(),
        algorithm: 'RS256',
        privateKey: this.configService.get('file').privateKey,
      },
    );
  }
}
