func (ct *createTranslations) createTranslationFileWithGoogleTranslate(language string) (string, error) {
	fileName, _, err := common.CheckFile(ct.Filename)
	if err != nil {
		return "", err
	}

	err = common.CreateOutputDirsIfNeeded(ct.OutputDirname)
	if err != nil {
		ct.Println(err)
		return "", fmt.Errorf("i18n4go: could not create output directory: %s", ct.OutputDirname)
	}

	destFilename := filepath.Join(ct.OutputDirname, strings.Replace(fileName, ct.options.SourceLanguageFlag, language, -1))

	i18nStringInfos, err := common.LoadI18nStringInfos(ct.Filename)
	if err != nil {
		ct.Println(err)
		return "", fmt.Errorf("i18n4go: could not load i18n strings from file: %s", ct.Filename)
	}

	if len(i18nStringInfos) == 0 {
		return "", fmt.Errorf("i18n4go: input file: %s is empty", ct.Filename)
	}

	ct.Println("i18n4go: attempting to use Google Translate to translate source strings in: ", language)
	modifiedI18nStringInfos := make([]common.I18nStringInfo, len(i18nStringInfos))
	for i, i18nStringInfo := range i18nStringInfos {
		translation, _, err := ct.googleTranslate(i18nStringInfo.Translation, language)
		if err != nil {
			ct.Println("i18n4go: error invoking Google Translate for string:", i18nStringInfo.Translation)
		} else {
			modifiedI18nStringInfos[i] = common.I18nStringInfo{ID: i18nStringInfo.ID, Translation: translation}
		}
	}

	err = common.SaveI18nStringInfos(ct, ct.Options(), modifiedI18nStringInfos, destFilename)
	if err != nil {
		ct.Println(err)
		return "", fmt.Errorf("i18n4go: could not save Google Translate i18n strings to file: %s", destFilename)
	}

	if ct.options.PoFlag {
		poFilename := destFilename[:len(destFilename)-len(".json")] + ".po"
		err = common.SaveI18nStringsInPo(ct, ct.Options(), modifiedI18nStringInfos, poFilename)
		if err != nil {
			ct.Println(err)
			return "", fmt.Errorf("i18n4go: could not save PO file: %s", poFilename)
		}
	}

	ct.Println()

	return destFilename, nil
}
func (vs *verifyStrings) generateInvalidTranslationDiffFile(invalidStringInfos []common.I18nStringInfo, fileName string) (string, error) {
	name, pathName, err := common.CheckFile(fileName)
	if err != nil {
		return "", err
	}

	diffFilename := name + ".invalid.diff.json"
	if vs.OutputDirname != "" {
		common.CreateOutputDirsIfNeeded(vs.OutputDirname)
		diffFilename = filepath.Join(vs.OutputDirname, diffFilename)
	} else {
		diffFilename = filepath.Join(pathName, diffFilename)
	}

	return diffFilename, common.SaveI18nStringInfos(vs, vs.Options(), invalidStringInfos, diffFilename)
}
func (vs *verifyStrings) Run() error {
	fileName, filePath, err := common.CheckFile(vs.InputFilename)
	if err != nil {
		vs.Println("i18n4go: Error checking input filename: ", vs.InputFilename)
		return err
	}

	targetFilenames := vs.determineTargetFilenames(fileName, filePath)
	vs.Println("targetFilenames:", targetFilenames)
	for _, targetFilename := range targetFilenames {
		err = vs.verify(vs.InputFilename, targetFilename)
		if err != nil {
			vs.Println("i18n4go: Error verifying target filename: ", targetFilename)
		}
	}

	return err
}
func (ct *createTranslations) createTranslationFile(sourceFilename string, language string) (string, error) {
	fileName, _, err := common.CheckFile(sourceFilename)
	if err != nil {
		return "", err
	}

	i18nStringInfos, err := common.LoadI18nStringInfos(sourceFilename)
	if err != nil {
		ct.Println(err)
		return "", fmt.Errorf("i18n4go: could not load i18n strings from file: %s", sourceFilename)
	}

	if len(i18nStringInfos) == 0 {
		return "", fmt.Errorf("i18n4go: input file: %s is empty", sourceFilename)
	}

	destFilename := filepath.Join(ct.OutputDirname, strings.Replace(fileName, ct.options.SourceLanguageFlag, language, -1))
	ct.Println("i18n4go: creating translation file:", destFilename)

	return destFilename, common.CopyFileContents(sourceFilename, destFilename)
}
func (vs *verifyStrings) verify(inputFilename string, targetFilename string) error {
	common.CheckFile(targetFilename)

	inputI18nStringInfos, err := common.LoadI18nStringInfos(inputFilename)
	if err != nil {
		vs.Println("i18n4go: Error loading the i18n strings from input filename:", inputFilename)
		return err
	}

	if len(inputI18nStringInfos) == 0 {
		return fmt.Errorf("i18n4go: Error input file: %s is empty", inputFilename)
	}

	inputMap, err := common.CreateI18nStringInfoMap(inputI18nStringInfos)
	if err != nil {
		return fmt.Errorf("File has duplicated key: %s\n%s", inputFilename, err)
	}

	targetI18nStringInfos, err := common.LoadI18nStringInfos(targetFilename)
	if err != nil {
		vs.Println("i18n4go: Error loading the i18n strings from target filename:", targetFilename)
		return err
	}

	var targetExtraStringInfos, targetInvalidStringInfos []common.I18nStringInfo
	for _, stringInfo := range targetI18nStringInfos {
		if _, ok := inputMap[stringInfo.ID]; ok {
			if common.IsTemplatedString(stringInfo.ID) && vs.isTemplatedStringTranslationInvalid(stringInfo) {
				vs.Println("i18n4go: WARNING target file has invalid templated translations with key ID: ", stringInfo.ID)
				targetInvalidStringInfos = append(targetInvalidStringInfos, stringInfo)
			}
			delete(inputMap, stringInfo.ID)
		} else {
			vs.Println("i18n4go: WARNING target file has extra key with ID: ", stringInfo.ID)
			targetExtraStringInfos = append(targetExtraStringInfos, stringInfo)
		}
	}

	var verficationError error
	if len(targetExtraStringInfos) > 0 {
		vs.Println("i18n4go: WARNING target file contains total of extra keys:", len(targetExtraStringInfos))

		diffFilename, err := vs.generateExtraKeysDiffFile(targetExtraStringInfos, targetFilename)
		if err != nil {
			vs.Println("i18n4go: ERROR could not create the diff file:", err)
			return err
		}
		vs.Println("i18n4go: generated diff file:", diffFilename)
		verficationError = fmt.Errorf("i18n4go: target file has extra i18n strings with IDs: %s", strings.Join(keysForI18nStringInfos(targetExtraStringInfos), ","))
	}

	if len(targetInvalidStringInfos) > 0 {
		vs.Println("i18n4go: WARNING target file contains total of invalid translations:", len(targetInvalidStringInfos))

		diffFilename, err := vs.generateInvalidTranslationDiffFile(targetInvalidStringInfos, targetFilename)
		if err != nil {
			vs.Println("i18n4go: ERROR could not create the diff file:", err)
			return err
		}
		vs.Println("i18n4go: generated diff file:", diffFilename)
		verficationError = fmt.Errorf("i18n4go: target file has invalid i18n strings with IDs: %s", strings.Join(keysForI18nStringInfos(targetInvalidStringInfos), ","))
	}

	if len(inputMap) > 0 {
		vs.Println("i18n4go: ERROR input file does not match target file:", targetFilename)

		diffFilename, err := vs.generateMissingKeysDiffFile(valuesForI18nStringInfoMap(inputMap), targetFilename)
		if err != nil {
			vs.Println("i18n4go: ERROR could not create the diff file:", err)
			return err
		}
		vs.Println("i18n4go: generated diff file:", diffFilename)
		verficationError = fmt.Errorf("i18n4go: target file is missing i18n strings with IDs: %s", strings.Join(keysForI18nStringInfoMap(inputMap), ","))
	}

	return verficationError
}