"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeviceInstallAppService = void 0;
const constants_1 = require("../../constants");
const path = require("path");
const yok_1 = require("../../common/yok");
class DeviceInstallAppService {
    constructor($analyticsService, $buildArtifactsService, $buildInfoFileService, $fs, $logger, $mobileHelper, $projectDataService, $platformsDataService) {
        this.$analyticsService = $analyticsService;
        this.$buildArtifactsService = $buildArtifactsService;
        this.$buildInfoFileService = $buildInfoFileService;
        this.$fs = $fs;
        this.$logger = $logger;
        this.$mobileHelper = $mobileHelper;
        this.$projectDataService = $projectDataService;
        this.$platformsDataService = $platformsDataService;
    }
    installOnDevice(device, buildData, packageFile) {
        return __awaiter(this, void 0, void 0, function* () {
            this.$logger.info(`Installing on device ${device.deviceInfo.identifier}...`);
            const platform = device.deviceInfo.platform.toLowerCase();
            const projectData = this.$projectDataService.getProjectData(buildData.projectDir);
            const platformData = this.$platformsDataService.getPlatformData(platform, projectData);
            yield this.$analyticsService.trackEventActionInGoogleAnalytics({
                action: "Deploy",
                device,
                projectDir: projectData.projectDir,
            });
            if (!packageFile) {
                packageFile = yield this.$buildArtifactsService.getLatestAppPackagePath(platformData, buildData);
            }
            yield platformData.platformProjectService.cleanDeviceTempFolder(device.deviceInfo.identifier, projectData);
            const appIdentifier = projectData.projectIdentifiers[platform];
            const outputFilePath = buildData.outputPath || platformData.getBuildOutputPath(buildData);
            yield device.applicationManager.reinstallApplication(appIdentifier, packageFile, buildData);
            yield this.updateHashesOnDevice({
                device,
                appIdentifier,
                outputFilePath,
                platformData,
            });
            if (!buildData.release) {
                yield this.$buildInfoFileService.saveDeviceBuildInfo(device, projectData, outputFilePath);
            }
            this.$logger.info(`Successfully installed on device with identifier '${device.deviceInfo.identifier}'.`);
        });
    }
    installOnDeviceIfNeeded(device, buildData, packageFile) {
        return __awaiter(this, void 0, void 0, function* () {
            const shouldInstall = yield this.shouldInstall(device, buildData);
            if (shouldInstall) {
                yield this.installOnDevice(device, buildData, packageFile);
            }
        });
    }
    shouldInstall(device, buildData) {
        return __awaiter(this, void 0, void 0, function* () {
            const projectData = this.$projectDataService.getProjectData(buildData.projectDir);
            const platformData = this.$platformsDataService.getPlatformData(device.deviceInfo.platform, projectData);
            const platform = device.deviceInfo.platform;
            if (!(yield device.applicationManager.isApplicationInstalled(projectData.projectIdentifiers[platform.toLowerCase()]))) {
                return true;
            }
            const deviceBuildInfo = yield this.$buildInfoFileService.getDeviceBuildInfo(device, projectData);
            const localBuildInfo = this.$buildInfoFileService.getLocalBuildInfo(platformData, Object.assign(Object.assign({}, buildData), { buildForDevice: !device.isEmulator }));
            return (!localBuildInfo ||
                !deviceBuildInfo ||
                deviceBuildInfo.buildTime !== localBuildInfo.buildTime);
        });
    }
    updateHashesOnDevice(data) {
        return __awaiter(this, void 0, void 0, function* () {
            const { device, appIdentifier, platformData, outputFilePath } = data;
            if (!this.$mobileHelper.isAndroidPlatform(platformData.normalizedPlatformName)) {
                return;
            }
            let hashes = {};
            const hashesFilePath = path.join(outputFilePath, constants_1.HASHES_FILE_NAME);
            if (this.$fs.exists(hashesFilePath)) {
                hashes = this.$fs.readJson(hashesFilePath);
            }
            yield device.fileSystem.updateHashesOnDevice(hashes, appIdentifier);
        });
    }
}
exports.DeviceInstallAppService = DeviceInstallAppService;
yok_1.injector.register("deviceInstallAppService", DeviceInstallAppService);
