# -*- coding: utf-8 -*-
import os
import sys
import subprocess
import csv
import numpy

from subprocess import STDOUT, check_output, CalledProcessError

from rmtk import __file__ as rmtk_path
from rmtk.vulnerability.common import utils

# FIXME we should not write data on the python package folder!
# For now it works only when installed with 'pip -e'
bin_directory = os.path.join(os.path.dirname(os.path.abspath(rmtk_path)),
                             '../bin')
package_directory = os.path.dirname(os.path.abspath(__file__))


def calculate_fragility(capacity_curves, hysteresis, msa, gmrs, damage_model,
                        damping, degradation):

    no_damage_states = len(damage_model['damage_states'])
    no_bins = msa['n. bins']
    no_rec_bin = msa['records per bin']
    no_gmrs = no_bins*no_rec_bin
    no_capacity_curves = len(capacity_curves['Sd'])
    PDM = numpy.zeros((no_bins, no_damage_states+1))
    Sds = numpy.zeros((no_gmrs, no_capacity_curves))
    gmr_info = numpy.zeros((no_gmrs, 2))

    for icc in range(no_capacity_curves):
        print str((icc+1)*100/no_capacity_curves) + '%'
        folder_scaled_recs = msa['input folder']
        target_files = os.listdir(folder_scaled_recs)
        for ele in target_files:
            if ele[-3:] != 'csv':
                target_files.remove(ele)
        counter = 0
        for index, ibin in enumerate(target_files):
            if index < no_bins:
                print ibin
            else:
                break

            with open(folder_scaled_recs+'/'+ibin, 'rb') as f:
                reader = csv.reader(f)
                newlist = [row for row in reader]
            record_name = [ele[0] for ele in newlist]
            record_scaling = [float(ele[1]) for ele in newlist]

            for igmr in range(no_rec_bin):
                limit_states = utils.define_limit_states(capacity_curves, icc,
                                                         damage_model)
                target_name = record_name[igmr]
                scaling_factor = record_scaling[igmr]
                time, disps = run_time_history_analysis(capacity_curves,
                                                        hysteresis, icc, gmrs,
                                                        target_name,
                                                        scaling_factor,
                                                        damping,
                                                        degradation)
                Sdi = max(numpy.abs(numpy.array(disps)))
                # with open('dynamicResult.csv', 'rb') as f:
                # reader = csv.reader(f)
                # newlist = [row[0] for row in reader]
                # if newlist == ['KO']:
                #    ds = no_ls
                [PDM, ds] = utils.allocate_damage(index, PDM, Sdi,
                                                  limit_states)
                gmr_info[counter, :] = [gmrs['name'].index(target_name),
                                        scaling_factor]
                Sds[counter][icc] = Sdi
                counter = counter+1
                print "gmr n.", counter, "max disp. =", Sdi, "DS =", ds

    return PDM, Sds, gmr_info


def run_time_history_analysis(capacity_curves, hysteresis, icc, gmrs,
                              target_name, scaling_factor, damping,
                              degradation):

    igmr = gmrs['name'].index(target_name)
    write_gmr(gmrs, igmr, scaling_factor)
    create_SDOF_paramfile(capacity_curves, hysteresis, icc, damping,
                          degradation)

    tcl = os.path.join(package_directory, "simplestSDOFgen.tcl")

    try:
        if 'darwin' in sys.platform:
            check_output([os.path.join(bin_directory,
                         "OpenSees.mac"), tcl],
                         cwd=package_directory, stderr=STDOUT)
        elif 'linux' in sys.platform:
            check_output([os.path.join(bin_directory,
                         "OpenSees.u1604"), tcl],
                         cwd=package_directory, stderr=STDOUT)
        else:
            sys.exit('Your OS is not currently support')
    except CalledProcessError as e:
        print(e.output)
        raise

    disps = []
    time = []
    disp_file = open(os.path.join(package_directory, 'NodeD.out'))
    lines = disp_file.readlines()
    for line in lines:
        values = line.strip().split(' ')
        time.append(float(values[0]))
        disps.append(float(values[1]))

    return time, disps


def write_gmr(gmrs, igmr, scaling_factor):
    out_file = open(os.path.join(package_directory, 'gmr.txt'), 'w')
    out_file.write(str(gmrs['no_points'][igmr])+'\n')
    out_file.write(str(gmrs['dt'][igmr])+'\n')
    for iacc in range(gmrs['no_points'][igmr]):
        out_file.write(str(gmrs['acc'][igmr][iacc]*scaling_factor)+'\n')
    out_file.close()


def create_SDOF_paramfile(capacity_curves, hysteresis, icc, damping,
                          degradation):

    d_flag = 0
    if degradation:
        d_flag = 1

    out_file = open(os.path.join(package_directory, 'SDOF_paramfile.tcl'), 'w')
    out_file.write('set material "pinchgeneric" \n')
    f1 = capacity_curves['Sa'][icc][1]*9.81
    f2 = capacity_curves['Sa'][icc][2]*9.81
    f3 = capacity_curves['Sa'][icc][3]*9.81
    f4 = capacity_curves['Sa'][icc][4]*9.81
    d1 = capacity_curves['Sd'][icc][1]
    d2 = capacity_curves['Sd'][icc][2]
    d3 = capacity_curves['Sd'][icc][3]
    d4 = capacity_curves['Sd'][icc][4]
    d5 = capacity_curves['Sd'][icc][4]
    # -capacity_curves['Sd'][icc][1]
    out_file.write('set fi {%f %f %f %f 0.0} \n' % (f1, f2, f3, f4))
    out_file.write('set di {%f %f %f %f %f} \n' % (d1, d2, d3, d4, d5))
    out_file.write('set ksi %f \n' % damping)
    out_file.write('set Tperiod "0.0" \n')
    out_file.write('set mx "1.0" \n')
    out_file.write('set degflag "%d" \n' % d_flag)
    out_file.write('set analysistype "dynamic" \n')
    out_file.write('set pinchingtype "%s" \n' % hysteresis['type'])

    if hysteresis['type'] == 'user-defined':
        out_file.write('set rDisp %f \n' % hysteresis['rDisp'][0])
        out_file.write('set fForce %f \n' % hysteresis['fForce'][0])
        out_file.write('set uForce %f \n' % hysteresis['uForce'][0])
        gK1, gK2, gK3, gK4, gKLim = hysteresis['gK'][0]
        gD1, gD2, gD3, gD4, gDLim = hysteresis['gD'][0]
        gF1, gF2, gF3, gF4, gFLim = hysteresis['gF'][0]
        out_file.write('set gammaK [list %f %f %f %f %f]\n' % (gK1, gK2, gK3,
                                                               gK4, gKLim))
        out_file.write('set gammaD [list %f %f %f %f %f]\n' % (gD1, gD2, gD3,
                                                               gD4, gDLim))
        out_file.write('set gammaF [list %f %f %f %f %f]\n' % (gF1, gF2, gF3,
                                                               gF4, gFLim))
        out_file.write('set gammaE %f \n' % hysteresis['gE'][0])
        out_file.write('set damage "%s"\n' % hysteresis['dmgType'][0])

    out_file.close()
