function normalizePlatforms(rawPlatforms: Array<string | Platform> | string | Platform | null | undefined): Array<Platform> {
  const platforms = rawPlatforms == null || Array.isArray(rawPlatforms) ? (rawPlatforms as Array<string | Platform | null | undefined>) : [rawPlatforms]
  if (platforms as any == null || platforms.length === 0) {
    return [Platform.fromString(process.platform)]
  }
  else if (platforms[0] === "all") {
    if (process.platform === Platform.MAC.nodeName) {
      return [Platform.MAC, Platform.LINUX, Platform.WINDOWS]
    }
    else if (process.platform === Platform.LINUX.nodeName) {
      // macOS code sign works only on macOS
      return [Platform.LINUX, Platform.WINDOWS]
    }
    else {
      return [Platform.WINDOWS]
    }
  }
  else {
    return platforms.map(it => it instanceof Platform ? it : Platform.fromString(it!))
  }
}
 return platforms.map(it => it instanceof Platform ? it : Platform.fromString(it!))
export function normalizeOptions(args: CliOptions): BuildOptions {
  if ((args as any).extraMetadata != null) {
    throw new InvalidConfigurationError("Please specify extraMetadata under config field")
  }

  if (args.targets != null) {
    return args
  }

  if ((args as any).draft != null || (args as any).prerelease != null) {
    log.warn({solution: "set releaseType (http://electron.build/configuration/publish#GithubOptions-releaseType) in the GitHub publish options"}, "--draft and --prerelease is deprecated")
  }

  let targets = new Map<Platform, Map<Arch, Array<string>>>()

  function processTargets(platform: Platform, types: Array<string>) {
    function commonArch(currentIfNotSpecified: boolean): Array<Arch> {
      if (platform === Platform.MAC) {
        return args.x64 || currentIfNotSpecified ? [Arch.x64] : []
      }

      const result = Array<Arch>()
      if (args.x64) {
        result.push(Arch.x64)
      }
      if (args.armv7l) {
        result.push(Arch.armv7l)
      }
      if (args.arm64) {
        result.push(Arch.arm64)
      }
      if (args.ia32) {
        result.push(Arch.ia32)
      }

      return result.length === 0 && currentIfNotSpecified ? [archFromString(process.arch)] : result
    }

    if (args.platform != null) {
      throw new InvalidConfigurationError(`--platform cannot be used if --${platform.buildConfigurationKey} is passed`)
    }
    if (args.arch != null) {
      throw new InvalidConfigurationError(`--arch cannot be used if --${platform.buildConfigurationKey} is passed`)
    }

    let archToType = targets.get(platform)
    if (archToType == null) {
      archToType = new Map<Arch, Array<string>>()
      targets.set(platform, archToType)
    }

    if (types.length === 0) {
      const defaultTargetValue = args.dir ? [DIR_TARGET] : []
      for (const arch of commonArch(args.dir === true)) {
        archToType.set(arch, defaultTargetValue)
      }
      return
    }

    for (const type of types) {
      const suffixPos = type.lastIndexOf(":")
      if (suffixPos > 0) {
        addValue(archToType, archFromString(type.substring(suffixPos + 1)), type.substring(0, suffixPos))
      }
      else {
        for (const arch of commonArch(true)) {
          addValue(archToType, arch, type)
        }
      }
    }
  }

  if (args.mac != null) {
    processTargets(Platform.MAC, args.mac)
  }

  if (args.linux != null) {
    processTargets(Platform.LINUX, args.linux)
  }

  if (args.win != null) {
    processTargets(Platform.WINDOWS, args.win)
  }

  if (targets.size === 0) {
    if (args.platform == null && args.arch == null) {
      processTargets(Platform.current(), [])
    }
    else {
      targets = createTargets(normalizePlatforms(args.platform), args.dir ? DIR_TARGET : null, args.arch)
    }
  }

  const result = {...args}
  result.targets = targets

  delete result.dir
  delete result.mac
  delete result.linux
  delete result.win
  delete result.platform
  delete result.arch

  const r = result as any
  delete r.m
  delete r.o
  delete r.l
  delete r.w
  delete r.windows
  delete r.macos
  delete r.$0
  delete r._
  delete r.version
  delete r.help
  delete r.c
  delete r.p
  delete r.pd

  delete result.ia32
  delete result.x64
  delete result.armv7l
  delete result.arm64

  let config = result.config

  // config is array when combining dot-notation values with a config file value
  // https://github.com/electron-userland/electron-builder/issues/2016
  if (Array.isArray(config)) {
    const newConfig: Configuration = {}
    for (const configItem of config) {
      if (typeof configItem === "object") {
        deepAssign(newConfig, configItem)
      }
      else if (typeof configItem === "string") {
        newConfig.extends = configItem
      }
    }

    config = newConfig
    result.config = newConfig
  }

  if (config != null && typeof config !== "string") {
    if (config.extraMetadata != null) {
      coerceTypes(config.extraMetadata)
    }
    if (config.mac != null) {
      // ability to disable code sign using -c.mac.identity=null
      coerceValue(config.mac, "identity")
    }
  }

  if ("project" in r && !("projectDir" in result)) {
    result.projectDir = r.project
  }
  delete r.project

  return result as BuildOptions
}