"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.generateUniversalIconAsync = generateUniversalIconAsync;
exports.getIcons = getIcons;
exports.setIconsAsync = setIconsAsync;
exports.withIosIcons = void 0;
function _configPlugins() {
  const data = require("@expo/config-plugins");
  _configPlugins = function () {
    return data;
  };
  return data;
}
function _Target() {
  const data = require("@expo/config-plugins/build/ios/Target");
  _Target = function () {
    return data;
  };
  return data;
}
function _imageUtils() {
  const data = require("@expo/image-utils");
  _imageUtils = function () {
    return data;
  };
  return data;
}
function _fs() {
  const data = _interopRequireDefault(require("fs"));
  _fs = function () {
    return data;
  };
  return data;
}
function _path() {
  const data = _interopRequireDefault(require("path"));
  _path = function () {
    return data;
  };
  return data;
}
function _AssetContents() {
  const data = require("./AssetContents");
  _AssetContents = function () {
    return data;
  };
  return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
  getProjectName
} = _configPlugins().IOSConfig.XcodeUtils;
const IMAGE_CACHE_NAME = 'icons';
const IMAGESET_PATH = 'Images.xcassets/AppIcon.appiconset';
const withIosIcons = config => {
  config = (0, _configPlugins().withDangerousMod)(config, ['ios', async config => {
    await setIconsAsync(config, config.modRequest.projectRoot);
    return config;
  }]);
  config = (0, _configPlugins().withXcodeProject)(config, config => {
    const icon = getIcons(config);
    const projectName = config.modRequest.projectName;
    if (icon && typeof icon === 'string' && _path().default.extname(icon) === '.icon' && projectName) {
      const iconName = _path().default.basename(icon, '.icon');
      setIconName(config.modResults, projectName, iconName);
      addIconFileToProject(config.modResults, projectName, iconName);
    }
    return config;
  });
  return config;
};
exports.withIosIcons = withIosIcons;
function getIcons(config) {
  const iosSpecificIcons = config.ios?.icon;
  if (iosSpecificIcons) {
    // For backwards compatibility, the icon can be a string
    if (typeof iosSpecificIcons === 'string') {
      return iosSpecificIcons || config.icon || null;
    }
    if (typeof iosSpecificIcons === 'object') {
      const paths = [iosSpecificIcons.light, iosSpecificIcons.dark, iosSpecificIcons.tinted].filter(Boolean);
      for (const iconPath of paths) {
        if (typeof iconPath === 'string' && _path().default.extname(iconPath) === '.icon') {
          _configPlugins().WarningAggregator.addWarningIOS('icon', `Liquid glass icons (.icon) should be provided as a string to the "ios.icon" property, not as an object. Found: "${iconPath}"`);
        }
      }
    }

    // in iOS 18 introduced the ability to specify dark and tinted icons, which users can specify as an object
    if (!iosSpecificIcons.light && !iosSpecificIcons.dark && !iosSpecificIcons.tinted) {
      return config.icon || null;
    }
    return iosSpecificIcons;
  }

  // Top level icon property should not be used to specify a `.icon` folder
  if (config.icon && typeof config.icon === 'string' && _path().default.extname(config.icon) === '.icon') {
    _configPlugins().WarningAggregator.addWarningIOS('icon', `Liquid glass icons (.icon) should be provided via the "ios.icon" property, not the root "icon" property. Found: "${config.icon}"`);
  }
  if (config.icon) {
    return config.icon;
  }
  return null;
}
async function setIconsAsync(config, projectRoot) {
  const icon = getIcons(config);
  if (!icon || typeof icon === 'string' && !icon || typeof icon === 'object' && !icon?.light && !icon?.dark && !icon?.tinted) {
    _configPlugins().WarningAggregator.addWarningIOS('icon', 'No icon is defined in the Expo config.');
  }

  // Something like projectRoot/ios/MyApp/
  const iosNamedProjectRoot = getIosNamedProjectPath(projectRoot);
  if (typeof icon === 'string' && _path().default.extname(icon) === '.icon') {
    return await addLiquidGlassIcon(icon, projectRoot, iosNamedProjectRoot);
  }

  // Ensure the Images.xcassets/AppIcon.appiconset path exists
  await _fs().default.promises.mkdir(_path().default.join(iosNamedProjectRoot, IMAGESET_PATH), {
    recursive: true
  });
  const imagesJson = [];
  const baseIconPath = typeof icon === 'object' ? icon?.light || icon?.dark || icon?.tinted : icon;

  // Store the image JSON data for assigning via the Contents.json
  const baseIcon = await generateUniversalIconAsync(projectRoot, {
    icon: baseIconPath,
    cacheKey: 'universal-icon',
    iosNamedProjectRoot,
    platform: 'ios'
  });
  imagesJson.push(baseIcon);
  if (typeof icon === 'object') {
    if (icon?.dark) {
      const darkIcon = await generateUniversalIconAsync(projectRoot, {
        icon: icon.dark,
        cacheKey: 'universal-icon-dark',
        iosNamedProjectRoot,
        platform: 'ios',
        appearance: 'dark'
      });
      imagesJson.push(darkIcon);
    }
    if (icon?.tinted) {
      const tintedIcon = await generateUniversalIconAsync(projectRoot, {
        icon: icon.tinted,
        cacheKey: 'universal-icon-tinted',
        iosNamedProjectRoot,
        platform: 'ios',
        appearance: 'tinted'
      });
      imagesJson.push(tintedIcon);
    }
  }

  // Finally, write the Contents.json
  await (0, _AssetContents().writeContentsJsonAsync)(_path().default.join(iosNamedProjectRoot, IMAGESET_PATH), {
    images: imagesJson
  });
}

/**
 * Return the project's named iOS path: ios/MyProject/
 *
 * @param projectRoot Expo project root path.
 */
function getIosNamedProjectPath(projectRoot) {
  const projectName = getProjectName(projectRoot);
  return _path().default.join(projectRoot, 'ios', projectName);
}
function getAppleIconName(size, scale, appearance) {
  let name = 'App-Icon';
  if (appearance) {
    name = `${name}-${appearance}`;
  }
  name = `${name}-${size}x${size}@${scale}x.png`;
  return name;
}
async function generateUniversalIconAsync(projectRoot, {
  icon,
  cacheKey,
  iosNamedProjectRoot,
  platform,
  appearance
}) {
  const size = 1024;
  const filename = getAppleIconName(size, 1, appearance);
  let source;
  if (icon) {
    // Using this method will cache the images in `.expo` based on the properties used to generate them.
    // this method also supports remote URLs and using the global sharp instance.
    source = (await (0, _imageUtils().generateImageAsync)({
      projectRoot,
      cacheType: IMAGE_CACHE_NAME + cacheKey
    }, {
      src: icon,
      name: filename,
      width: size,
      height: size,
      // Transparency needs to be preserved in dark variant, but can safely be removed in "light" and "tinted" variants.
      removeTransparency: appearance !== 'dark',
      // The icon should be square, but if it's not then it will be cropped.
      resizeMode: 'cover',
      // Force the background color to solid white to prevent any transparency. (for "any" and "tinted" variants)
      // TODO: Maybe use a more adaptive option based on the icon color?
      backgroundColor: appearance !== 'dark' ? '#ffffff' : undefined
    })).source;
  } else {
    // Create a white square image if no icon exists to mitigate the chance of a submission failure to the app store.
    source = await (0, _imageUtils().createSquareAsync)({
      size
    });
  }
  // Write image buffer to the file system.
  const assetPath = _path().default.join(iosNamedProjectRoot, IMAGESET_PATH, filename);
  await _fs().default.promises.writeFile(assetPath, source);
  return {
    filename,
    idiom: 'universal',
    platform,
    size: `${size}x${size}`,
    ...(appearance ? {
      appearances: [{
        appearance: 'luminosity',
        value: appearance
      }]
    } : {})
  };
}
async function addLiquidGlassIcon(iconPath, projectRoot, iosNamedProjectRoot) {
  const iconName = _path().default.basename(iconPath, '.icon');
  const sourceIconPath = _path().default.join(projectRoot, iconPath);
  const targetIconPath = _path().default.join(iosNamedProjectRoot, `${iconName}.icon`);
  if (!_fs().default.existsSync(sourceIconPath)) {
    _configPlugins().WarningAggregator.addWarningIOS('icon', `Liquid glass icon file not found at path: ${iconPath}`);
    return;
  }
  await _fs().default.promises.cp(sourceIconPath, targetIconPath, {
    recursive: true
  });
}

/**
 * Adds the .icons name to the project
 */
function setIconName(project, projectName, iconName) {
  const [, target] = (0, _Target().findNativeTargetByName)(project, projectName);
  const configurations = _configPlugins().IOSConfig.XcodeUtils.getBuildConfigurationsForListId(project, target.buildConfigurationList);
  for (const [, config] of configurations) {
    if (config?.buildSettings) {
      config.buildSettings.ASSETCATALOG_COMPILER_APPICON_NAME = iconName;
    }
  }
}

/**
 * Adds the .icon file to the project
 */
function addIconFileToProject(project, projectName, iconName) {
  const iconPath = `${iconName}.icon`;
  _configPlugins().IOSConfig.XcodeUtils.addResourceFileToGroup({
    filepath: `${projectName}/${iconPath}`,
    groupName: projectName,
    project,
    isBuildFile: true,
    verbose: true
  });
}
//# sourceMappingURL=withIosIcons.js.map