// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the License.txt file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;

namespace TestUtilities
{
    public class TempFile
    {
        private readonly string _path;

        internal TempFile(string path)
        {
            _path = path;
        }

        internal TempFile(string? prefix, string? extension, string? directory, string? callerSourcePath, int callerLineNumber)
        {
            while (true)
            {
                if (prefix == null)
                {
                    prefix = System.IO.Path.GetFileName(callerSourcePath) + "_" + callerLineNumber.ToString() + "_";
                }

                _path = System.IO.Path.Combine(directory ?? TempRoot.Root, prefix + Guid.NewGuid() + (extension ?? ".tmp"));

                try
                {
                    TempRoot.CreateStream(_path);
                    break;
                }
                catch (PathTooLongException)
                {
                    throw;
                }
                catch (DirectoryNotFoundException)
                {
                    throw;
                }
                catch (IOException)
                {
                    // retry
                }
            }
        }

        public FileStream Open(FileAccess access = FileAccess.ReadWrite)
        {
            return new FileStream(_path, FileMode.Open, access);
        }

        public string Path
        {
            get { return _path; }
        }

        public TempFile WriteAllText(string content, Encoding encoding)
        {
            File.WriteAllText(_path, content, encoding);
            return this;
        }

        public TempFile WriteAllText(string content)
        {
            File.WriteAllText(_path, content);
            return this;
        }

        public async Task<TempFile> WriteAllTextAsync(string content, Encoding encoding)
        {
            using (var sw = new StreamWriter(File.Create(_path), encoding))
            {
                await sw.WriteAsync(content).ConfigureAwait(false);
            }

            return this;
        }

        public Task<TempFile> WriteAllTextAsync(string content)
        {
            return WriteAllTextAsync(content, Encoding.UTF8);
        }

        public TempFile WriteAllBytes(byte[] content)
        {
            File.WriteAllBytes(_path, content);
            return this;
        }

        public string ReadAllText()
        {
            return File.ReadAllText(_path);
        }

        public byte[] ReadAllBytes()
        {
            return File.ReadAllBytes(_path);
        }

        public TempFile CopyContentFrom(string path)
        {
            return WriteAllBytes(File.ReadAllBytes(path));
        }

        public override string ToString()
        {
            return _path;
        }
    }
}
