package com.airlock.iam.admin.infrastructure.service.token.airlock2fa;

import com.airlock.iam.admin.api.domain.service.user.ManagedUserRepository;
import com.airlock.iam.admin.domain.model.token.airlock2fa.Airlock2FAShipmentLetter;
import com.airlock.iam.admin.domain.service.token.airlock2fa.Airlock2FAShipmentLetterPrintingService;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.misc.file.FileName;
import com.airlock.iam.core.misc.util.report.ReportRenderer;
import com.airlock.iam.core.misc.util.report.ReportRendererAgent;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class Airlock2FAShipmentLetterPrintingServiceImpl implements Airlock2FAShipmentLetterPrintingService {
   static final String FILE_NAME_PREFIX = "airlock-2fa-shipment";
   private final ManagedUserRepository userRepository;
   private final Optional<String> languageAttributeName;
   private final ReportRendererAgent rendererAgent;

   public Airlock2FAShipmentLetterPrintingServiceImpl(
      ManagedUserRepository userRepository,
      ReportRenderer renderer,
      Path outputDirectory,
      Optional<Path> workingDirectory,
      Optional<String> languageAttributeName
   ) {
      this(userRepository, languageAttributeName, new ReportRendererAgent(renderer, outputDirectory, workingDirectory));
   }

   Airlock2FAShipmentLetterPrintingServiceImpl(ManagedUserRepository userRepository, Optional<String> languageAttributeName, ReportRendererAgent rendererAgent) {
      this.userRepository = userRepository;
      this.languageAttributeName = languageAttributeName;
      this.rendererAgent = rendererAgent;
   }

   @Override
   public Path printToFile(UserId userId, Airlock2FAShipmentLetter shipmentLetter) {
      Map<String, Object> allParameters = this.parameters(shipmentLetter);
      return this.rendererAgent
         .render(
            allParameters,
            this.languageAttributeName,
            FileName.builder()
               .prefix("airlock-2fa-shipment")
               .delimiterAfterPrefix(true)
               .element(userId.getValue())
               .element(shipmentLetter.getId().asString())
               .build()
         );
   }

   private Map<String, Object> parameters(Airlock2FAShipmentLetter shipmentLetter) {
      Map<String, Object> parameters = new HashMap<>(this.contextData(shipmentLetter.getDeviceOwner()));
      parameters.put("deviceSerialNumber", shipmentLetter.getDeviceSerialNumber());
      parameters.put("deviceActivationCode", shipmentLetter.getDeviceActivationCode().orElse(null));
      parameters.put("deviceManufacturer", shipmentLetter.getDeviceManufacturer());
      parameters.put("deviceModel", shipmentLetter.getDeviceModel());
      return parameters;
   }

   private Map<String, Object> contextData(UserId userId) {
      return this.userRepository.getById(userId).getContextData().asKeyValueMap();
   }
}
