"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createAndWriteIconsToPathAsync = createAndWriteIconsToPathAsync;

function _fsExtra() {
  const data = _interopRequireDefault(require("fs-extra"));

  _fsExtra = function () {
    return data;
  };

  return data;
}

function _path() {
  const data = _interopRequireDefault(require("path"));

  _path = function () {
    return data;
  };

  return data;
}

function _globby() {
  const data = _interopRequireDefault(require("globby"));

  _globby = function () {
    return data;
  };

  return data;
}

function _ExponentTools() {
  const data = require("./ExponentTools");

  _ExponentTools = function () {
    return data;
  };

  return data;
}

function _ImageUtils() {
  const data = require("../tools/ImageUtils");

  _ImageUtils = function () {
    return data;
  };

  return data;
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const iconScales = {
  mdpi: 1,
  hdpi: 1.5,
  xhdpi: 2,
  xxhdpi: 3,
  xxxhdpi: 4
};

async function _regexFileInResSubfoldersAsync(oldText, newText, resDirPath, folderPrefix, folderSuffix, fileName) {
  return Promise.all(Object.keys(iconScales).map(async key => {
    return (0, _ExponentTools().regexFileAsync)(oldText, newText, _path().default.join(resDirPath, `${folderPrefix}${key}${folderSuffix}`, fileName));
  }));
}

let _hasShownResizeErrorWindowsLinux = false;

async function _resizeIconsAsync(context, resPath, prefix, mdpiSize, filename, url, isDetached) {
  let baseImagePath = _path().default.join(resPath, filename);

  try {
    if (isDetached) {
      const data = context.data;
      await (0, _ExponentTools().saveImageToPathAsync)(data.projectPath, url, baseImagePath);
    } else {
      await (0, _ExponentTools().saveUrlToPathAsync)(url, baseImagePath);
    }
  } catch (e) {
    throw new Error(`Failed to save icon file to disk. (${e})`);
  }

  await Promise.all(Object.entries(iconScales).map(async ([folderSuffix, iconScale]) => {
    // adaptive icons (mdpiSize 108) must be placed in a -v26 folder
    let subdirectoryName = `${prefix}${folderSuffix}${mdpiSize === 108 ? '-v26' : ''}`;

    let destinationPath = _path().default.join(resPath, subdirectoryName);

    await (0, _ExponentTools().spawnAsyncThrowError)('/bin/cp', [baseImagePath, filename], {
      stdio: 'inherit',
      cwd: destinationPath
    });

    try {
      await (0, _ImageUtils().resizeImageAsync)(mdpiSize * iconScale, filename, destinationPath);
    } catch (e) {
      // Turtle should be able to resize images, so if it fails we want it to throw.
      // However, `sips` does not exist on Windows or Linux machines, so we expect
      // resizing images to error on these OSes and want the detach process to continue anyway.
      if (isDetached) {
        if (!_hasShownResizeErrorWindowsLinux) {
          console.warn('Failed to resize app icons. Your full size icon will be copied to all android/app/src/main/res directories. For best quality, we recommend providing downscaled versions.');
          _hasShownResizeErrorWindowsLinux = true;
        }
      } else {
        throw new Error(`Failed to resize image: ${filename}. ${e}`);
      }
    } // reject non-square icons


    const dims = await (0, _ImageUtils().getImageDimensionsAsync)(destinationPath, filename);

    if (!dims) {
      // Again, only throw this error on Turtle -- we expect that this will fail
      // for some detach users but we don't want this to stop the whole process.
      if (!isDetached) {
        throw new Error(`Unable to read the dimensions of ${filename}`);
      }
    } else if (dims.width !== dims.height) {
      throw new Error(`Android icons must be square, the dimensions of ${filename} are ${dims}`);
    }
  }));
  await (0, _ExponentTools().spawnAsyncThrowError)('/bin/rm', [baseImagePath]);
}

async function createAndWriteIconsToPathAsync(context, resPath, isDetached) {
  let manifest = context.config; // manifest or app.json

  let iconUrl = manifest.android && manifest.android.iconUrl ? manifest.android.iconUrl : manifest.iconUrl;
  let notificationIconUrl = manifest.notification ? manifest.notification.iconUrl : null;

  if (isDetached) {
    // manifest is actually just app.json in this case, so iconUrl fields don't exist
    iconUrl = manifest.android && manifest.android.icon ? manifest.android.icon : manifest.icon;
    notificationIconUrl = manifest.notification ? manifest.notification.icon : null;
  }

  let iconBackgroundUrl;
  let iconBackgroundColor;
  let iconForegroundUrl;

  if (manifest.android && manifest.android.adaptiveIcon) {
    iconBackgroundColor = manifest.android.adaptiveIcon.backgroundColor;

    if (isDetached) {
      iconForegroundUrl = manifest.android.adaptiveIcon.foregroundImage;
      iconBackgroundUrl = manifest.android.adaptiveIcon.backgroundImage;
    } else {
      iconForegroundUrl = manifest.android.adaptiveIcon.foregroundImageUrl;
      iconBackgroundUrl = manifest.android.adaptiveIcon.backgroundImageUrl;
    }
  }

  if (iconUrl || iconForegroundUrl) {
    // Android 7 and below icon
    if (iconUrl) {
      (await (0, _globby().default)(['**/ic_launcher.png'], {
        cwd: resPath,
        absolute: true
      })).forEach(filePath => {
        _fsExtra().default.removeSync(filePath);
      });
      await _resizeIconsAsync(context, resPath, 'mipmap-', 48, 'ic_launcher.png', iconUrl, isDetached);
    } // Adaptive icon foreground image


    if (iconForegroundUrl) {
      (await (0, _globby().default)(['**/ic_foreground.png'], {
        cwd: resPath,
        absolute: true
      })).forEach(filePath => {
        _fsExtra().default.removeSync(filePath);
      });
      await _resizeIconsAsync(context, resPath, 'mipmap-', 108, 'ic_foreground.png', iconForegroundUrl, isDetached);
    } else {
      // the OS's default method of coercing normal app icons to adaptive
      // makes them look quite different from using an actual adaptive icon (with xml)
      // so we need to support falling back to the old version on Android 8
      (await (0, _globby().default)(['**/mipmap-*-v26/*'], {
        cwd: resPath,
        absolute: true,
        dot: true
      })).forEach(filePath => {
        _fsExtra().default.removeSync(filePath);
      });

      try {
        (await (0, _globby().default)(['**/mipmap-*-v26'], {
          cwd: resPath,
          absolute: true
        })).forEach(filePath => {
          _fsExtra().default.rmdirSync(filePath);
        });
      } catch (e) {// we don't want the entire detach script to fail if node
        // can't remove the directories for whatever reason.
        // people can remove the directories themselves if they need
        // so just fail silently here
      }
    }
  } // Adaptive icon background image or color


  if (iconBackgroundUrl) {
    await _resizeIconsAsync(context, resPath, 'mipmap-', 108, 'ic_background.png', iconBackgroundUrl, isDetached);
    await _regexFileInResSubfoldersAsync('@color/iconBackground', '@mipmap/ic_background', resPath, 'mipmap-', '-v26', 'ic_launcher.xml');
  } else if (iconBackgroundColor) {
    await (0, _ExponentTools().regexFileAsync)('"iconBackground">#FFFFFF', `"iconBackground">${iconBackgroundColor}`, _path().default.join(resPath, 'values', 'colors.xml'));
  } // Notification icon


  if (notificationIconUrl) {
    (await (0, _globby().default)(['**/shell_notification_icon.png'], {
      cwd: resPath,
      absolute: true
    })).forEach(filePath => {
      _fsExtra().default.removeSync(filePath);
    });
    await _resizeIconsAsync(context, resPath, 'drawable-', 24, 'shell_notification_icon.png', notificationIconUrl, isDetached);
  }
}
//# sourceMappingURL=../__sourcemaps__/detach/AndroidIcons.js.map