import numpy as np
import copy
import time
import matplotlib
import matplotlib.pyplot as  plt
import csv
import init
from vatest import *
#from virtual_force import *
numfbs = 0
nummbs = 0
sumgbs = nummbs + numfbs
R_mbs = 5
R_uav = 25
snrth = -5
itermax = 500
init_upper = 20
num1 = 1.01
num2 = 0
num3 = 5
num4 = 0
font_set = matplotlib.font_manager.FontProperties(fname=r"HYQiHei-60S.ttf")


class UE:
    def __init__(self):
        self.loc = [0, 0, 0]
        self.snrth = 0


class BS:
    def __init__(self):
        self.loc = [0, 0, 0]
        self.sort = 'UAV'
        self.power_upper = 0
        self.power_allocation = []  # 长度为用户数
        self.power_a2a = 0
        self.power = 0
        self.rate = 0
        self.rate_upper = 0


def read_UElist(ue_addr):
    ue_list = []
    with open(ue_addr, 'r') as f:
        f = csv.reader(f, delimiter=',')
        next(f)
        for row in f:
            ue_list.append(row)
    for i in range(len(ue_list)):
        ue_list[i] = list(map(float, ue_list[i]))
    UE_list = []
    for i in range(len(ue_list)):
        new_ue = UE()
        new_ue.loc = [ue_list[i][0], ue_list[i][1], 0]
        new_ue.sort = 'ue'
        new_ue.snrth = snrth
        UE_list.append(new_ue)
    return UE_list


def main():
    addr = r"D:\pycharm\va_3d\data\list_ue120_2.csv"
    # 导入用户位置
    UE_list = read_UElist(addr)
    print(len(UE_list), UE_list[0].loc)
    # 确定用户通信需求 各用户所需的信噪比
    numuav = 5
    BS_list = init.main3(UE_list.copy(), sumgbs, R_mbs=R_mbs, sumuav=numuav, R_uav=R_uav)
    fig = plt.figure('fig')
    fig.clf()

    for i in range(len(UE_list)):
        plt.scatter(UE_list[i].loc[0], UE_list[i].loc[1], color='blue', marker='x', s=40)
    plt.scatter(UE_list[i].loc[0], UE_list[i].loc[1], color='blue', marker='x', s=40, label='UE')
    plt.xlim(-10, 110)
    plt.ylim(-10, 110)

    snr, dist = cal_snr(UE_list, BS_list)

    link, linked = comm_connection(UE_list, BS_list, snr)  # 未建立连接的确保发射功率为0
    draw_uavus_link(UE_list, BS_list, linked, basecolor='red', size=40, )
    # draw_uav_update(BS_list, basecolor='k', LoSscale=1, size=20)
    pic_name = 'deployprocess'
    title = pic_name + str(numuav) + '.jpg'
    plt.legend(loc='upper right', borderaxespad=num4, prop=font_set)
    fig.savefig(title)
    coverate = cal_coverate(link)
    # 计算覆盖率 以及连接情况
    print(coverate)
    # 对于未被覆盖的边缘用户来说，目前调整位置并不能为他们提供服务
    # 那么如何继续对位置进行调整 或者能不能对功率进行调整从而实现服务呢
    # 约束：覆盖，功率
    # 计算引力，计算斥力
    times = 0
    init_times = 0
    total_rate = []
    total_rate1 = []
    total_rate.append(cal_network_rate(BS_list, UE_list))
    total_rate1.append(cal_network_rate(BS_list, UE_list))
    start = time.time()
    # 求最小数量
    while (coverate != 1):
        # 位置调整
        Fa, Fa_list = virtual_fa(UE_list, BS_list)
        Fr, Fr_list = virtual_fr(BS_list)

        F = total_force(Fa, Fr)
        v = force2v(F)
        move_length = update_state_position(BS_list, v)
        snr, dist = cal_snr(UE_list, BS_list)
        link, linked = comm_connection(UE_list, BS_list, snr)  # 确立连接关系 未建立连接的确保功率为0
        update_bs_power(BS_list)
        coverate = cal_coverate(link)

        if (coverate == 1):
            print(times, '实现全覆盖，退出迭代')
            break
        # 重新初始化
        if (coverate != 1) and init_times <= init_upper:

            print('此次无法全覆盖，重新初始化', numuav, coverate)
            BS_list = init.main3(UE_list.copy(), sumgbs, R_mbs=R_mbs, sumuav=numuav, R_uav=R_uav)

        elif (coverate != 1):
            print('无法全覆盖，增加无人机数量并重新初始化', numuav, coverate)
            init_times = 0
            numuav += 1

            BS_list = init.main3(UE_list.copy(), sumgbs, R_mbs=R_mbs, sumuav=numuav, R_uav=R_uav)
            snr, dist = cal_snr(UE_list, BS_list)
            link, linked = comm_connection(UE_list, BS_list, snr)  # 确立连接关系 未建立连接的确保功率为0
            fig = plt.figure('fig')
            fig.clf()

            for i in range(len(UE_list)):
                plt.scatter(UE_list[i].loc[0], UE_list[i].loc[1], color='blue', marker='x', s=40)
            plt.scatter(UE_list[i].loc[0], UE_list[i].loc[1], color='blue', marker='x', s=40, label='UE')
            plt.xlim(-10, 110)
            plt.ylim(-10, 110)
            draw_uavus_link(UE_list, BS_list, linked, basecolor='red', size=40, )
            # draw_uav_update(BS_list, basecolor='k', LoSscale=1, size=20)
            pic_name = 'deployprocess'
            title = pic_name + str(numuav) + '.jpg'
            plt.legend(loc='upper right', borderaxespad=num4, prop=font_set)
            fig.savefig(title)
        init_times += 1  # """
        # times += 1
    fig = plt.figure('fig')
    fig.clf()

    for i in range(len(UE_list)):
        plt.scatter(UE_list[i].loc[0], UE_list[i].loc[1], color='blue', marker='x', s=40)
    plt.scatter(UE_list[i].loc[0], UE_list[i].loc[1], color='blue', marker='x', s=40, label='UE')
    plt.xlim(-10, 110)
    plt.ylim(-10, 110)
    draw_uavus_link(UE_list, BS_list, linked, basecolor='red', size=40, )
    # draw_uav_update(BS_list, basecolor='k', LoSscale=1, size=20)
    pic_name = 'deployprocess'
    plt.legend(loc='upper right', borderaxespad=num4, prop=font_set)
    title = pic_name + str(numuav) + '.jpg'
    fig.savefig(title)

    # plt.show()
    # """
    BS_list1 = copy.deepcopy(BS_list)
    while (times < itermax):
        power_ = []
        # 位置调整
        Fa, Fa_list = virtual_fa(UE_list, BS_list)
        Fr, Fr_list = virtual_fr(BS_list)

        F = total_force(Fa, Fr)
        v = force2v(F)
        move_length = update_state_position(BS_list, v)
        snr, dist = cal_snr(UE_list, BS_list)
        link, linked = comm_connection(UE_list, BS_list, snr)  # 确立连接关系 未建立连接的确保功率为0
        update_bs_power(BS_list)

        # 功率调整
        Fa, Fa_list = virtual_fa(UE_list, BS_list)
        Fr, Fr_list = virtual_fr(BS_list)

        va = force2v(Fa, Max_Speed=power_step)
        va_list = forcelist2vlist(Fa_list)  # 引力
        vr_list = power2v(total_fr_power(Fr_list), Max_Speed=power_step)
        # update_state_power(BS_list, va_list, vr_list, link)
        update_state_power2(BS_list, va, vr_list, link)
        update_bs_power(BS_list)
        for i in range(len(BS_list)):
            power_.append(BS_list[i].power)
        snr, dist = cal_snr(UE_list, BS_list)
        link, linked = comm_connection(UE_list, BS_list, snr)  # 确立连接关系 未建立连接的确保功率为0
        coverate = cal_coverate(link)
        total_rate.append(cal_network_rate(BS_list, UE_list))

        print(times, coverate)

        # if move_length < 1:
        #    break
        times += 1

    total_time = time.time() - start
    # 只进行位置调整
    times = 0

    while (times < itermax):
        power_ = []
        # 位置调整
        Fa, Fa_list = virtual_fa(UE_list, BS_list1)
        Fr, Fr_list = virtual_fr(BS_list1)

        F = total_force(Fa, Fr)
        v = force2v(F)
        move_length = update_state_position(BS_list1, v)
        snr, dist = cal_snr(UE_list, BS_list1)
        link, linked = comm_connection(UE_list, BS_list1, snr)  # 确立连接关系 未建立连接的确保功率为0
        update_bs_power(BS_list1)

        total_rate1.append(cal_network_rate(BS_list1, UE_list))

        print(times, coverate)

        # if move_length < 1:
        #    break
        times += 1  # """

    # """
    print('用时', total_time)
    plt.figure()
    for i in range(len(UE_list)):
        plt.scatter(UE_list[i].loc[0], UE_list[i].loc[1], color='blue', marker='x', s=40)
    plt.xlim(-10, 110)
    plt.ylim(-10, 110)

    draw_uav_update(BS_list, basecolor='k', LoSscale=1, size=20)

    plt.figure()

    x = np.arange(len(total_rate))
    plt.plot(x, total_rate1, 'b-', label='optimize position only')
    plt.plot(x, total_rate, 'g-', label='jointly optimize position ans power')
    plt.xlabel('iterations', fontproperties=font_set)
    plt.ylabel('system throughput（bit/s·Hz）', fontproperties=font_set)
    plt.legend(loc='center right', borderaxespad=num4, prop=font_set)
    pic_name = 'plot'
    title = pic_name + '.jpg'
    fig.savefig(title)
    plt.figure()
    x = np.arange(len(total_rate))
    plt.plot(x, total_rate, 'g-', label='位置功率联合优化')
    plt.xlabel('迭代次数 耗时%.2f s' % total_time, fontproperties=font_set)
    plt.ylabel('系统吞吐量（bit/s·Hz）', fontproperties=font_set)
    plt.legend(loc='center right', borderaxespad=num4, prop=font_set)
    plt.show()  # """


if __name__ == '__main__':
    main()
