using System.ComponentModel;
using Evos.Api.Repository;
using Evos.Core.Container.ProjectScope;
using Evos.ModelsRepository;
using Evos.ModelsRepository.BasicData;
using Evos.ModelsRepository.DataProvider.TransactionDescriptions;
using Evos.ModelsRepository.SpaceModel;

namespace Evos.Api.Samples.Infrastructure
{
    /// Одноразовый локальный репозиторий во временной папке: сэмплам нужно куда-то писать,
    /// а поднимать Collaboration-сервер ради демонстрации незачем.
    /// Как открыть репозиторий по-настоящему — показано в RepositoryLifecycleSample.
    [Localizable(false)]
    internal sealed class SampleRepository : IDisposable
    {
        // Базовый продукт, который Evos заводит в каждом проекте. В «пустом» репозитории он уже есть,
        // и сэмплы учитывают его при подсчётах.
        private const string BaseProductName = "Компонент";

        private readonly IProjectLocation _location;

        private SampleRepository(IProjectLocation location, IConcurrentRepository repository)
        {
            _location = location;
            Repository = repository;
        }

        public IConcurrentRepository Repository { get; }

        /// Пустой репозиторий без единого продукта.
        public static SampleRepository CreateNew()
        {
            var directory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var location = new ProjectLocation(directory, Path.GetRandomFileName());

            return new SampleRepository(location, new ApiConcurrentRepositoryFactory().OpenNewRepository(location));
        }

        /// Репозиторий с базовым продуктом — таким его видит Evos в реальном проекте.
        public static SampleRepository CreateWithBaseProduct()
        {
            var sampleRepository = CreateNew();

            sampleRepository.Repository.TryExecuteTransaction(
                writeAccess => writeAccess.NewNamedProduct(BaseProductName, ProductKind.Designed),
                new TransactionInfo(TransactionDescription.AddingProduct, TransactionMode.Default));

            return sampleRepository;
        }

        public void Dispose()
        {
            Repository.Dispose();
            Directory.Delete(_location.Directory, true);
        }
    }
}
