using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MachUtilPlanner
{
    public class MUPExtension
    {
        public static int MaxInd(int[] array)
        {
            int index = 0;
            for (int i = 1; i < array.Length; i++)
                if (array[i] > array[index])
                    index = i;
            return index;
        }

        public static MachUtilProblem Reduce(MachUtilProblem P, out int T)
        {
            int W = P.Total, i, index = 0, n = P.Dimension;
            int[] ut = new int[n], t0 = new int[n], ct = new int[n];
            P.UseTime.CopyTo(ut, 0);
            P.T0.CopyTo(t0, 0);
            for (i = 0; i < n; i++)
            {
                ct[i] = (int)Math.Round(1.0 / P.FailureRateFunction(P.UseTime[i])) - P.T0[i];
                if (ct[i] < 1)
                    ct[i] = 1;
                if (ct[i] < ct[index])
                    index = i;
            }
            i = 0;
            T = ct[index];
            while(ct[index] > 0 && W > 0)
            {
                W -= n;
                for (i = 0; i < n; i++)
                {
                    ct[i]--;
                    ut[i]++;
                    t0[i]++;
                }
            }
            T -= ct[index];
            MachUtilProblem P1 = new MachUtilProblem(P.FailureRateFunction, (W > 0) ? W : 0, n, P.MaintenanceTime, P.Weight, ut, t0);
            P1.cT = ct;
            return P1;
        }

        public static int[] MinNom(MachUtilProblem P, out int K)
        {
            int W = P.Total, i, sel, n = P.Dimension;
            int[] x = new int[n], T = new int[n], cT = new int[n];
            P.UseTime.CopyTo(T, 0);
            if (P.cT == null)
            {
                for (i = 0; i < n; i++)
                {
                    cT[i] = (int)Math.Round(1.0 / P.FailureRateFunction(T[i])) - P.T0[i];
                    if (cT[i] < 0)
                        cT[i] = 0;
                }
            }
            else
                P.cT.CopyTo(cT, 0);
            for (i = 0; i < n; i++)
            {
                if (W > cT[i])
                {
                    x[i] += cT[i];
                    W -= cT[i];
                }
                else
                {
                    x[i] += W;
                    W = 0;
                    break;
                }
                T[i] += cT[i];
                cT[i] = (int)Math.Round(1.0 / P.FailureRateFunction(T[i]));
                if (cT[i] < 1)
                    cT[i] = 1;
            }
            K = 0;
            while (W > 0)
            {
                sel = MaxInd(cT);
                if (W > cT[sel])
                {
                    x[sel] += cT[sel];
                    W -= cT[sel];
                }
                else
                {
                    x[sel] += W;
                    W = 0;
                    break;
                }
                T[sel] += cT[sel];
                cT[sel] = (int)Math.Round(1.0 / P.FailureRateFunction(T[sel]));
                K++;
            }
            if(x.Sum() != P.Total)
                W = 0;
            return x;
        }

    }
}
