package com.mjm.solarInsertDB;

import com.csvreader.CsvWriter;

import javax.baja.naming.BOrd;
import javax.baja.nre.annotations.NiagaraAction;
import javax.baja.nre.annotations.NiagaraProperty;
import javax.baja.nre.annotations.NiagaraSlots;
import javax.baja.nre.annotations.NiagaraType;
import javax.baja.sys.*;
import javax.baja.util.BNotification;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * Created by user on 2017/4/7.
 */
@NiagaraType
@NiagaraSlots(
        properties =
                {
                        @NiagaraProperty(name = "DatabaseInformation", type = "BDatabaseInformation",defaultValue = "new BDatabaseInformation()",flags =Flags.SUMMARY ),
                        @NiagaraProperty(name = "disable", type = "boolean", defaultValue = "true",flags =Flags.SUMMARY ),
                        @NiagaraProperty(name = "exception", type = "boolean", defaultValue = "false",flags =Flags.SUMMARY ),
                        @NiagaraProperty(name = "working", type = "boolean", defaultValue = "false",flags =Flags.SUMMARY ),
                        @NiagaraProperty(name = "showMessage", type = "boolean", defaultValue = "true",flags =Flags.SUMMARY ),
                        @NiagaraProperty(name = "path", type = "String", defaultValue = "",flags =Flags.SUMMARY ),
                        @NiagaraProperty(name = "fileName", type = "String", defaultValue = "",flags =Flags.SUMMARY )
                },
        actions =
        {
                @NiagaraAction(name = "insert"),
                @NiagaraAction(name = "setField",parameterType = "BInteger",defaultValue ="BInteger.make(1)" )
        }
)
//@NiagaraActions(
//        @NiagaraAction(name = "insert"),
//        @NiagaraAction(name = "setField",parameterType = "BInteger",defaultValue = "BInteger.make(0)")
//)


public class BInsertData2 extends BComponent {
/*+ ------------ BEGIN BAJA AUTO GENERATED CODE ------------ +*/
/*@ $com.mjm.solarInsertDB.BInsertData(1564231253)1.0$ @*/
/* Generated Fri Mar 07 22:21:47 CST 2025 by Slot-o-Matic (c) Tridium, Inc. 2012 */

////////////////////////////////////////////////////////////////
// Property "DatabaseInformation"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code DatabaseInformation} property.
   * @see #getDatabaseInformation
   * @see #setDatabaseInformation
   */
  public static final Property DatabaseInformation = newProperty(Flags.SUMMARY, new BDatabaseInformation(), null);
  
  /**
   * Get the {@code DatabaseInformation} property.
   * @see #DatabaseInformation
   */
  public BDatabaseInformation getDatabaseInformation() { return (BDatabaseInformation)get(DatabaseInformation); }
  
  /**
   * Set the {@code DatabaseInformation} property.
   * @see #DatabaseInformation
   */
  public void setDatabaseInformation(BDatabaseInformation v) { set(DatabaseInformation, v, null); }

////////////////////////////////////////////////////////////////
// Property "disable"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code disable} property.
   * @see #getDisable
   * @see #setDisable
   */
  public static final Property disable = newProperty(Flags.SUMMARY, true, null);
  
  /**
   * Get the {@code disable} property.
   * @see #disable
   */
  public boolean getDisable() { return getBoolean(disable); }
  
  /**
   * Set the {@code disable} property.
   * @see #disable
   */
  public void setDisable(boolean v) { setBoolean(disable, v, null); }

////////////////////////////////////////////////////////////////
// Property "exception"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code exception} property.
   * @see #getException
   * @see #setException
   */
  public static final Property exception = newProperty(Flags.SUMMARY, false, null);
  
  /**
   * Get the {@code exception} property.
   * @see #exception
   */
  public boolean getException() { return getBoolean(exception); }
  
  /**
   * Set the {@code exception} property.
   * @see #exception
   */
  public void setException(boolean v) { setBoolean(exception, v, null); }

////////////////////////////////////////////////////////////////
// Property "working"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code working} property.
   * @see #getWorking
   * @see #setWorking
   */
  public static final Property working = newProperty(Flags.SUMMARY, false, null);
  
  /**
   * Get the {@code working} property.
   * @see #working
   */
  public boolean getWorking() { return getBoolean(working); }
  
  /**
   * Set the {@code working} property.
   * @see #working
   */
  public void setWorking(boolean v) { setBoolean(working, v, null); }

////////////////////////////////////////////////////////////////
// Property "showMessage"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code showMessage} property.
   * @see #getShowMessage
   * @see #setShowMessage
   */
  public static final Property showMessage = newProperty(Flags.SUMMARY, true, null);
  
  /**
   * Get the {@code showMessage} property.
   * @see #showMessage
   */
  public boolean getShowMessage() { return getBoolean(showMessage); }
  
  /**
   * Set the {@code showMessage} property.
   * @see #showMessage
   */
  public void setShowMessage(boolean v) { setBoolean(showMessage, v, null); }

////////////////////////////////////////////////////////////////
// Property "path"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code path} property.
   * @see #getPath
   * @see #setPath
   */
  public static final Property path = newProperty(Flags.SUMMARY, "", null);
  
  /**
   * Get the {@code path} property.
   * @see #path
   */
  public String getPath() { return getString(path); }
  
  /**
   * Set the {@code path} property.
   * @see #path
   */
  public void setPath(String v) { setString(path, v, null); }

////////////////////////////////////////////////////////////////
// Property "fileName"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code fileName} property.
   * @see #getFileName
   * @see #setFileName
   */
  public static final Property fileName = newProperty(Flags.SUMMARY, "", null);
  
  /**
   * Get the {@code fileName} property.
   * @see #fileName
   */
  public String getFileName() { return getString(fileName); }
  
  /**
   * Set the {@code fileName} property.
   * @see #fileName
   */
  public void setFileName(String v) { setString(fileName, v, null); }

////////////////////////////////////////////////////////////////
// Action "insert"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code insert} action.
   * @see #insert()
   */
  public static final Action insert = newAction(0, null);
  
  /**
   * Invoke the {@code insert} action.
   * @see #insert
   */
  public void insert() { invoke(insert, null, null); }

////////////////////////////////////////////////////////////////
// Action "setField"
////////////////////////////////////////////////////////////////
  
  /**
   * Slot for the {@code setField} action.
   * @see #setField(BInteger parameter)
   */
  public static final Action setField = newAction(0, BInteger.make(1), null);
  
  /**
   * Invoke the {@code setField} action.
   * @see #setField
   */
  public void setField(BInteger parameter) { invoke(setField, parameter, null); }

////////////////////////////////////////////////////////////////
// Type
////////////////////////////////////////////////////////////////
  
  @Override
  public Type getType() { return TYPE; }
  public static final Type TYPE = Sys.loadType(BInsertData2.class);

/*+ ------------ END BAJA AUTO GENERATED CODE -------------- +*/





    BDatabaseInformation databaseInformation = null;

    public void started() {
        databaseInformation = (BDatabaseInformation) this.getDatabaseInformation().asComponent();
        BOrd absolute = BOrd.make("station:|slot:/Services/PlatformServices/SystemService/hostId");
        String hostID = absolute.get().toString();

        System.out.println(this.getType().getTypeName() + " --onStarted-- " + hostID);


    }


    public void changed(Property property, Context context) {
        if (this.isRunning()) {
            if (property == databaseInformation) {
                System.out.println("in insert  data");
                databaseInformation = (BDatabaseInformation)this.databaseInformation.asComponent();
                // .getDatabaseInformation().asComponent();
            }
        }
    }

    public void doInsert() {

        System.out.println("0307 doInsert: ");
        if (1==1) {
        //    if (checkLicense.getLegal()) {

            ArrayList<String> fieldName = new ArrayList<String>();
            ArrayList<String> fieldValue = new ArrayList<String>();


            if (this.getDisable() || this.getException()) {
                if (this.getShowMessage()) {
                    System.out.println("disable or exception");
                }
            } else {
                try {
                    this.setWorking(true);

                    Property property[] = this.getDynamicPropertiesArray();

                    for (int i = 0; i < property.length; i++) {

                        if (property[i].getName().contains("Field")) {

                            BField field = (BField) this.get(property[i]).asComponent();

                            fieldName.add(field.getFieldName());
                            fieldValue.add(field.getFieldValue());
                        }
                    }

                    if (fieldName.size() == fieldValue.size()) {
//                        System.out.println(databaseInformation.getInsertToDatabase());
                        if (databaseInformation.getInsertToDatabase()) {
                            String insertCommand = makeInsertCommand(fieldName, fieldValue);
//                    System.out.println("insertCommand : "+insertCommand);
//                            ConnectInformation connectInformation = new ConnectInformation(databaseInformation.getDbIp(), databaseInformation.getDbName(), databaseInformation.getDbUser(), databaseInformation.getDbPassword(), databaseInformation.getDbTableName());
//                            MySQL mysql = new MySQL(connectInformation);
////
//                            mysql.insertSQLCommand(insertCommand);

                            // 建立连接
                            ConnectInformation connectInformation = new ConnectInformation();
                            Connection  connection = connectInformation.getSQLServerConnection(databaseInformation.getDbIp(), databaseInformation.getDbName(), databaseInformation.getDbUser(), databaseInformation.getDbPassword(), databaseInformation.getDbTableName());
                            System.out.println("------connection info: "+connection);
                            // 创建Statement
                            Statement  statement = connection.createStatement();
                            System.out.println("------insertCommand info: "+insertCommand);
                            // 执行查询
                           // statement.execute("insert into data (c0) values(23228);");
                            statement.execute(insertCommand);
                            statement.close();
                            connection.close();
                        }
                        createCSV(fieldName, fieldValue);


                    }
                } catch (Exception e) {
                    System.out.println(e);
                    this.setException(true);
                    e.printStackTrace();

                } finally {
                    this.setWorking(false);
                }


            }


        } else {

            System.out.println("no license!");
            BNotification note = new BNotification();
            note.add("title", BString.make("No License"));
            note.add("message", BString.make("Please contact FIC"));
            note.raise(true);

        }

    }


    public void doSetField(BInteger interger) {

        int number = interger.getInt();


        Property property[] = this.getDynamicPropertiesArray();


        for (int i = 0; i < property.length; i++) {

            if (property[i].getName().contains("Field")) {

                this.remove(property[i].getName());

            }
        }
        for (int i = 0; i < number; i++) {

            this.add("Field" + (i + 1), new BField());

        }

    }

    private void createCSV(ArrayList<String> fieldName, ArrayList<String> fieldValue) {

        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        String strDate = sdFormat.format(date);


        String outputFile = "../../shared/" + this.getPath() + strDate + this.getFileName();

// before we open the file check to see if it already exists
        boolean alreadyExists = new File(outputFile).exists();

        try {
            // use FileWriter constructor that specifies open for appending


            if (!alreadyExists) {

                deleteFile();

                if (!this.getPath().equals("")) {

                    File file = new File(outputFile);
                    file.getParentFile().mkdir();
                    try {
                        file.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }


            CsvWriter csvOutput = new CsvWriter(new FileWriter(outputFile, true), ',');

            // if the file didn't already exist then we need to write out the header line
            if (!alreadyExists) {


                for (int i = 0; i < fieldName.size(); i++) {
                    csvOutput.write(fieldName.get(i));


                }
                csvOutput.endRecord();
            }
            // else assume that the file already has the correct header line

            // write out a few records

            for (int i = 0; i < fieldValue.size(); i++) {

//                System.out.println(fieldValue.get(i));

                csvOutput.write(fieldValue.get(i));

            }

            csvOutput.endRecord();


            csvOutput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void deleteFile() {


        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -90);//90天前
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        String before90 = format.format(cal.getTime()) + " 00:00:00";

        System.out.println("delete file before " + before90);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));


        try {
            Date sDate = sdf.parse(before90);
            long beforeTimestamp = sDate.getTime() / 1000;
//            System.out.println(beforeTimestamp);


            String fullpath = "../../shared/" + this.getPath();

            File a = new File(fullpath);


            if (a.isDirectory()) {
                String[] filenames = a.list();
                for (int i = 0; i < filenames.length; i++) {
                    File tempFile = new File(fullpath + "\\" + filenames[i]);
                    if (tempFile.isDirectory()) {
                        System.out.println("目錄:" + filenames[i]);
                    } else {
//                        System.out.println("檔案:" + filenames[i]);

                        String dateName = filenames[i].split(" ")[0] + " 00:00:00";

                        sDate = sdf.parse(dateName);
                        long fileTimestamp = sDate.getTime() / 1000;

                        if (fileTimestamp < beforeTimestamp) {
                            System.out.println("delete file " + fullpath + filenames[i]);
                            File deleteFile = new File(fullpath + filenames[i]);
                            deleteFile.delete();

                        }


                    }
                }
            } else {
                System.out.println("[" + a + "]不是目錄");
            }


        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    private String makeInsertCommand(ArrayList<String> fieldName, ArrayList<String> fieldValue) {

        String command = "INSERT INTO " + databaseInformation.getDbName() + ".dbo." + databaseInformation.getDbTableName() + " (";
//INSERT INTO `fpgcenter`.`0071801` (`timestamp`, `inverterID`, `SN`, `status`, `AC1V`, `AC1A`, `AC1W`, `AC1F`, `AC1Wh`, `AC2V`, `AC2A`, `AC2W`, `AC2F`, `AC2Wh`, `AC3V`, `AC3A`, `AC3W`, `AC3F`, `AC3Wh`, `ACRT`, `DC1V`, `DC1A`, `DC1W`, `DC1Wh`, `DC2V`, `DC2A`, `DC2W`, `DC2Wh`, `DCRT`, `totalKWH`) VALUES ('1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1');

        for (int i = 0; i < fieldName.size(); i++) {

            command = command + fieldName.get(i) + ", ";

        }
        command = command.substring(0, command.length() - 2) + ") VALUES (";

        for (int i = 0; i < fieldValue.size(); i++) {

            command = command + "'" + fieldValue.get(i) + "', ";

        }

        command = command.substring(0, command.length() - 2) + ");";

        System.out.println("command: "+command);
        return command;

    }
    public void setDatabaseInformation(){

        databaseInformation = (BDatabaseInformation) this.getDatabaseInformation().asComponent();
    }
}
