// REQUIRES: objc_interop
// RUN: %empty-directory(%t.mod)
// RUN: %target-swift-frontend -emit-module -o %t.mod/Cities.swiftmodule %S/Inputs/Cities.swift -module-name Cities -parse-as-library
// RUN: %empty-directory(%t) && %target-swift-frontend -c -update-code -primary-file %s  -I %t.mod -api-diff-data-file %S/Inputs/string-representable.json -emit-migrated-file-path %t/string-representable.swift.result -disable-migrator-fixits -o /dev/null
// RUN: diff -u %S/string-representable.swift.expected %t/string-representable.swift.result

import Cities

func foo(_ c: Container) -> String {
  c.Value = convertToNewAttribute("")
  c.addingAttributes(convertToCitiesContainerAttributeDictionary(["a": "b", "a": "b", "a": "b"]))
  c.addingAttributes(convertToCitiesContainerAttributeDictionary(["a": "b", "a": "b", "a": "b"]))
  c.adding(attributes: convertToSimpleAttributeDictionary(["a": 1, "a": 2, "a": 3]))
  c.adding(optionalAttributes: convertToOptionalSimpleAttributeDictionary(["a": 1, "a": 2, "a": 3]))
  _ = Container(optionalAttributes: convertToOptionalSimpleAttributeDictionary([:]))
  _ = Container(optionalAttrArray: convertToOptionalSimpleAttributeArray([]))
  _ = Container(optionalAttributes: nil)
  _ = Container(optionalAttrArray: nil)
  c.adding(attrArray: convertToSimpleAttributeArray(["key1", "key2"]))
  c.add(single: convertToSimpleAttribute(""))
  c.add(singleOptional: convertToOptionalSimpleAttribute(""))
  c.add(singleOptional: nil)
  _ = convertFromSimpleAttributeDictionary(c.getAttrDictionary())
  _ = convertFromOptionalSimpleAttributeDictionary(c.getOptionalAttrDictionary())
  _ = convertFromSimpleAttribute(c.getSingleAttr())
  _ = convertFromOptionalSimpleAttribute(c.getOptionalSingleAttr())
  _ = convertFromSimpleAttributeArray(c.getAttrArray())
  _ = convertFromOptionalSimpleAttributeArray(c.getOptionalAttrArray())

  c.addingAttributes(convertToCitiesContainerAttributeDictionary(convertFromSimpleAttributeDictionary(c.getAttrDictionary())))
  c.adding(optionalAttributes: convertToOptionalSimpleAttributeDictionary(convertFromSimpleAttributeDictionary(c.getAttrDictionary())))

  c.attrDict = convertToSimpleAttributeDictionary(["a": "b", "a": "b", "a": "b"])
  c.attrArr = convertToSimpleAttributeArray(["key1", "key2"])
  _ = convertFromSimpleAttributeArray(c.attrArr)
  _ = convertFromSimpleAttributeDictionary(c.attrDict)
  c.adding(attributes: convertToSimpleAttributeDictionary(convertFromSimpleAttributeDictionary(c.attrDict)))
  _ = Container(optionalAttrArray: convertToOptionalSimpleAttributeArray(convertFromSimpleAttributeArray(c.attrArr)))
  c.adding(optionalAttributes: convertToOptionalSimpleAttributeDictionary(convertFromOptionalSimpleAttributeDictionary(c.optionalAttrDict)))
  _ = convertFromNewAttribute(AttributeWrapper.NewAttribute)
  c.Value = convertToNewAttribute(convertFromNewAttribute(AttributeWrapper.NewAttribute))
  c.optionalAttrDict = nil
  return convertFromNewAttribute(c.Value)
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToNewAttribute(_ input: String) -> NewAttribute {
	return NewAttribute(rawValue: input)
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToCitiesContainerAttributeDictionary(_ input: [String: Any]) -> [Cities.Container.Attribute: Any] {
	return Dictionary(uniqueKeysWithValues: input.map { key, value in (Cities.Container.Attribute(rawValue: key), value)})
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToSimpleAttributeDictionary(_ input: [String: Any]) -> [SimpleAttribute: Any] {
	return Dictionary(uniqueKeysWithValues: input.map { key, value in (SimpleAttribute(rawValue: key), value)})
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToOptionalSimpleAttributeDictionary(_ input: [String: Any]?) -> [SimpleAttribute: Any]? {
	guard let input = input else { return nil }
	return Dictionary(uniqueKeysWithValues: input.map { key, value in (SimpleAttribute(rawValue: key), value)})
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToOptionalSimpleAttributeArray(_ input: [String]?) -> [SimpleAttribute]? {
	guard let input = input else { return nil }
	return input.map { key in SimpleAttribute(key) }
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToSimpleAttributeArray(_ input: [String]) -> [SimpleAttribute] {
	return input.map { key in SimpleAttribute(key) }
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToSimpleAttribute(_ input: String) -> SimpleAttribute {
	return SimpleAttribute(rawValue: input)
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToOptionalSimpleAttribute(_ input: String?) -> SimpleAttribute? {
	guard let input = input else { return nil }
	return SimpleAttribute(rawValue: input)
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromSimpleAttributeDictionary(_ input: [SimpleAttribute: Any]) -> [String: Any] {
	return Dictionary(uniqueKeysWithValues: input.map {key, value in (key.rawValue, value)})
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromOptionalSimpleAttributeDictionary(_ input: [SimpleAttribute: Any]?) -> [String: Any]? {
	guard let input = input else { return nil }
	return Dictionary(uniqueKeysWithValues: input.map {key, value in (key.rawValue, value)})
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromSimpleAttribute(_ input: SimpleAttribute) -> String {
	return input.rawValue
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromOptionalSimpleAttribute(_ input: SimpleAttribute?) -> String? {
	guard let input = input else { return nil }
	return input.rawValue
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromSimpleAttributeArray(_ input: [SimpleAttribute]) -> [String] {
	return input.map { key in key.rawValue }
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromOptionalSimpleAttributeArray(_ input: [SimpleAttribute]?) -> [String]? {
	guard let input = input else { return nil }
	return input.map { key in key.rawValue }
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertFromNewAttribute(_ input: NewAttribute) -> String {
	return input.rawValue
}
