public static async Task <int> Validate(FileInfo modelFile, string repo, DependencyResolutionOption deps, bool strict)
        {
            Parsing parsing = new Parsing(repo);

            try
            {
                FileExtractResult extractResult = parsing.ExtractModels(modelFile);
                List <string>     models        = extractResult.Models;

                if (models.Count == 0)
                {
                    Outputs.WriteError("No models to validate.");
                    return(ReturnCodes.ValidationError);
                }

                ModelParser parser;
                if (models.Count > 1)
                {
                    // Special case: when validating from an array, only use array contents for resolution.
                    // Setup vanilla parser with no resolution. We get a better error message when a delegate is assigned.
                    parser = new ModelParser
                    {
                        DtmiResolver = (IReadOnlyCollection <Dtmi> dtmis) =>
                        {
                            return(Task.FromResult(Enumerable.Empty <string>()));
                        }
                    };
                }
                else
                {
                    parser = parsing.GetParser(resolutionOption: deps);
                }

                Outputs.WriteOut($"- Validating models conform to DTDL...");
                await parser.ParseAsync(models);

                if (strict)
                {
                    if (extractResult.ContentKind == JsonValueKind.Array || models.Count > 1)
                    {
                        // Related to file path validation.
                        Outputs.WriteError("Strict validation requires a single root model object.");
                        return(ReturnCodes.ValidationError);
                    }

                    string id = parsing.GetRootId(models[0]);
                    Outputs.WriteOut($"- Ensuring DTMIs namespace conformance for model \"{id}\"...");
                    List <string> invalidSubDtmis = Validations.EnsureSubDtmiNamespace(models[0]);
                    if (invalidSubDtmis.Count > 0)
                    {
                        Outputs.WriteError(
                            $"The following DTMI's do not start with the root DTMI namespace:{Environment.NewLine}{string.Join($",{Environment.NewLine}", invalidSubDtmis)}");
                        return(ReturnCodes.ValidationError);
                    }

                    // TODO: Evaluate changing how file path validation is invoked.
                    if (Validations.IsRemoteEndpoint(repo))
                    {
                        Outputs.WriteError($"Model file path validation requires a local repository.");
                        return(ReturnCodes.ValidationError);
                    }

                    Outputs.WriteOut($"- Ensuring model file path adheres to DMR path conventions...");
                    string filePathError = Validations.EnsureValidModelFilePath(modelFile.FullName, models[0], repo);

                    if (filePathError != null)
                    {
                        Outputs.WriteError(
                            $"File \"{modelFile.FullName}\" does not adhere to DMR path conventions. Expecting \"{filePathError}\".");
                        return(ReturnCodes.ValidationError);
                    }
                }
            }
            catch (ResolutionException resolutionEx)
            {
                Outputs.WriteError(resolutionEx.Message);
                return(ReturnCodes.ResolutionError);
            }
            catch (ResolverException resolverEx)
            {
                Outputs.WriteError(resolverEx.Message);
                return(ReturnCodes.ResolutionError);
            }
            catch (ParsingException parsingEx)
            {
                IList <ParsingError> errors = parsingEx.Errors;
                string normalizedErrors     = string.Empty;
                foreach (ParsingError error in errors)
                {
                    normalizedErrors += $"{Environment.NewLine}{error.Message}";
                }

                Outputs.WriteError(normalizedErrors);
                return(ReturnCodes.ValidationError);
            }
            catch (IOException ioEx)
            {
                Outputs.WriteError(ioEx.Message);
                return(ReturnCodes.InvalidArguments);
            }
            catch (ArgumentException argEx)
            {
                Outputs.WriteError(argEx.Message);
                return(ReturnCodes.InvalidArguments);
            }
            catch (System.Text.Json.JsonException jsonEx)
            {
                Outputs.WriteError($"Parsing json-ld content. Details: {jsonEx.Message}");
                return(ReturnCodes.InvalidArguments);
            }

            return(ReturnCodes.Success);
        }
        public static async Task <int> Import(FileInfo modelFile, DirectoryInfo localRepo, DependencyResolutionOption deps, bool strict)
        {
            if (localRepo == null)
            {
                localRepo = new DirectoryInfo(Path.GetFullPath("."));
            }

            Parsing parsing = new Parsing(localRepo.FullName);

            try
            {
                ModelParser       parser        = parsing.GetParser(resolutionOption: deps);
                FileExtractResult extractResult = parsing.ExtractModels(modelFile);
                List <string>     models        = extractResult.Models;

                if (models.Count == 0)
                {
                    Outputs.WriteError("No models to import.");
                    return(ReturnCodes.ValidationError);
                }

                Outputs.WriteOut($"- Validating models conform to DTDL...");
                await parser.ParseAsync(models);

                if (strict)
                {
                    foreach (string content in models)
                    {
                        string id = parsing.GetRootId(content);
                        Outputs.WriteOut($"- Ensuring DTMIs namespace conformance for model \"{id}\"...");
                        List <string> invalidSubDtmis = Validations.EnsureSubDtmiNamespace(content);
                        if (invalidSubDtmis.Count > 0)
                        {
                            Outputs.WriteError(
                                $"The following DTMI's do not start with the root DTMI namespace:{Environment.NewLine}{string.Join($",{Environment.NewLine}", invalidSubDtmis)}");
                            return(ReturnCodes.ValidationError);
                        }
                    }
                }

                foreach (string content in models)
                {
                    await ModelImporter.ImportAsync(content, localRepo);
                }
            }
            catch (ResolutionException resolutionEx)
            {
                Outputs.WriteError(resolutionEx.Message);
                return(ReturnCodes.ResolutionError);
            }
            catch (ResolverException resolverEx)
            {
                Outputs.WriteError(resolverEx.Message);
                return(ReturnCodes.ResolutionError);
            }
            catch (ParsingException parsingEx)
            {
                IList <ParsingError> errors = parsingEx.Errors;
                string normalizedErrors     = string.Empty;
                foreach (ParsingError error in errors)
                {
                    normalizedErrors += $"{Environment.NewLine}{error.Message}";
                }

                Outputs.WriteError(normalizedErrors);
                return(ReturnCodes.ValidationError);
            }
            catch (IOException ioEx)
            {
                Outputs.WriteError(ioEx.Message);
                return(ReturnCodes.InvalidArguments);
            }
            catch (ArgumentException argEx)
            {
                Outputs.WriteError(argEx.Message);
                return(ReturnCodes.InvalidArguments);
            }
            catch (System.Text.Json.JsonException jsonEx)
            {
                Outputs.WriteError($"Parsing json-ld content. Details: {jsonEx.Message}");
                return(ReturnCodes.InvalidArguments);
            }

            return(ReturnCodes.Success);
        }