def sla_dag_miss(sla_run_detail, serialized_dags_slas):
    """
    Generate SLA dag miss table giving us details about the SLA miss % for the given timeframes along with the average execution time and
    reccomendations for weekly observations.

    Args:
        sla_run_detail (dataframe): Base table consiting of details of all the dag runs that happened
        serialized_dags_slas (dataframe): table consisting of all the dag details

    Returns:
        2 lists consisting of sla_daily_miss and sla_dag_miss reccomendations and 1 dataframe consisting of sla_dag_miss reccomendation
    """
    try:

        dag_sla_count_df_weekprior, dag_sla_count_df_weekprior_avgduration = sla_miss_count_df(
            sla_run_detail, long_timeframe_start_date)
        dag_sla_count_df_threedayprior, dag_sla_count_df_threedayprior_avgduration = sla_miss_count_df(
            sla_run_detail, medium_timeframe_start_date)
        dag_sla_count_df_onedayprior, dag_sla_count_df_onedayprior_avgduration = sla_miss_count_df(
            sla_run_detail, short_timeframe_start_date)

        dag_sla_run_count_week_prior = sla_run_counts_df(sla_run_detail, long_timeframe_start_date)
        dag_sla_run_count_three_day_prior = sla_run_counts_df(sla_run_detail, medium_timeframe_start_date)
        dag_sla_run_count_one_day_prior = sla_run_counts_df(sla_run_detail, short_timeframe_start_date)

        dag_sla_run_count_week_prior_success = (
            dag_sla_run_count_week_prior[dag_sla_run_count_week_prior["state"] == "success"].groupby(
                ["dag_id", "task_id"]).size().to_frame(name="success_count").reset_index())
        dag_sla_run_count_week_prior_failure = (
            dag_sla_run_count_week_prior[dag_sla_run_count_week_prior["state"] == "failed"].groupby(
                ["dag_id", "task_id"]).size().to_frame(name="failure_count").reset_index())

        dag_sla_run_count_week_prior_success_duration_stats = (
            dag_sla_run_count_week_prior[dag_sla_run_count_week_prior["state"] == "success"].groupby(
                ["dag_id", "task_id"])["duration"].agg(["mean", "min", "max"]).reset_index())
        dag_sla_run_count_week_prior_failure_duration_stats = (
            dag_sla_run_count_week_prior[dag_sla_run_count_week_prior["state"] == "failed"].groupby(
                ["dag_id", "task_id"])["duration"].agg(["mean", "min", "max"]).reset_index())

        dag_sla_totalcount_week_prior = sla_total_counts_df(dag_sla_run_count_week_prior)
        dag_sla_totalcount_three_day_prior = sla_total_counts_df(dag_sla_run_count_three_day_prior)
        dag_sla_totalcount_one_day_prior = sla_total_counts_df(dag_sla_run_count_one_day_prior)

        dag_obs5_sladpercent_weekprior = sla_miss_pct(dag_sla_count_df_weekprior, dag_sla_totalcount_week_prior)
        dag_obs6_sladpercent_threedayprior = sla_miss_pct(dag_sla_count_df_threedayprior,
                                                          dag_sla_totalcount_three_day_prior)
        dag_obs7_sladpercent_onedayprior = sla_miss_pct(dag_sla_count_df_onedayprior, dag_sla_totalcount_one_day_prior)

        dag_obs7_sladetailed_week = f'In the past {str(LONG_TIMEFRAME_IN_DAYS)} days, {dag_obs5_sladpercent_weekprior}% of the tasks have missed their SLA'
        dag_obs6_sladetailed_threeday = f'In the past {str(MEDIUM_TIMEFRAME_IN_DAYS)} days, {dag_obs6_sladpercent_threedayprior}% of the tasks have missed their SLA'
        dag_obs5_sladetailed_oneday = f'In the past {str(SHORT_TIMEFRAME_IN_DAYS)} days, {dag_obs7_sladpercent_onedayprior}% of the tasks have missed their SLA'

        dag_sla_miss_pct_df_week_prior = pd.merge(
            pd.merge(dag_sla_count_df_weekprior, dag_sla_totalcount_week_prior, on=["dag_id", "task_id"]),
            dag_sla_count_df_weekprior_avgduration,
            on=["dag_id", "task_id"],
        )
        dag_sla_miss_pct_df_threeday_prior = pd.merge(
            pd.merge(
                dag_sla_count_df_threedayprior,
                dag_sla_totalcount_three_day_prior,
                on=["dag_id", "task_id"],
            ),
            dag_sla_count_df_threedayprior_avgduration,
            on=["dag_id", "task_id"],
        )
        dag_sla_miss_pct_df_oneday_prior = pd.merge(
            pd.merge(
                dag_sla_count_df_onedayprior,
                dag_sla_totalcount_one_day_prior,
                on=["dag_id", "task_id"],
            ),
            dag_sla_count_df_onedayprior_avgduration,
            on=["dag_id", "task_id"],
        )

        dag_sla_miss_pct_df_week_prior["sla_miss_percent_week"] = (
            dag_sla_miss_pct_df_week_prior["size"] * 100 / dag_sla_miss_pct_df_week_prior["total_count"]).round(2)
        dag_sla_miss_pct_df_threeday_prior["sla_miss_percent_three_day"] = (
            dag_sla_miss_pct_df_threeday_prior["size"] * 100 /
            dag_sla_miss_pct_df_threeday_prior["total_count"]).round(2)
        dag_sla_miss_pct_df_oneday_prior["sla_miss_percent_one_day"] = (
            dag_sla_miss_pct_df_oneday_prior["size"] * 100 / dag_sla_miss_pct_df_oneday_prior["total_count"]).round(2)

        dag_sla_miss_pct_df1 = dag_sla_miss_pct_df_week_prior.merge(dag_sla_miss_pct_df_threeday_prior,
                                                                    on=["dag_id", "task_id"],
                                                                    how="left")
        dag_sla_miss_pct_df2 = dag_sla_miss_pct_df1.merge(dag_sla_miss_pct_df_oneday_prior,
                                                          on=["dag_id", "task_id"],
                                                          how="left")
        dag_sla_miss_pct_df3 = dag_sla_miss_pct_df2.merge(serialized_dags_slas, on=["dag_id", "task_id"], how="left")

        dag_sla_miss_pct_detailed = dag_sla_miss_pct_df3.filter(
            [
                "dag_id",
                "task_id",
                "sla",
                "sla_miss_percent_week",
                "duration_x",
                "sla_miss_percent_three_day",
                "duration_y",
                "sla_miss_percent_one_day",
                "duration",
            ],
            axis=1,
        )

        float_column_names = dag_sla_miss_pct_detailed.select_dtypes(float).columns
        dag_sla_miss_pct_detailed[float_column_names] = dag_sla_miss_pct_detailed[float_column_names].fillna(0)

        round_int_column_names = ["duration_x", "duration_y", "duration"]
        dag_sla_miss_pct_detailed[round_int_column_names] = dag_sla_miss_pct_detailed[round_int_column_names].round(
            0).astype(int)
        dag_sla_miss_pct_detailed["sla"] = dag_sla_miss_pct_detailed["sla"].astype(int)
        dag_sla_miss_pct_detailed["Dag: Task"] = (dag_sla_miss_pct_detailed["dag_id"].apply(str) + ": " +
                                                  dag_sla_miss_pct_detailed["task_id"].apply(str))

        short_timeframe_col_name = f'{SHORT_TIMEFRAME_IN_DAYS}-day SLA Miss % (avg execution time)'
        medium_timeframe_col_name = f'{MEDIUM_TIMEFRAME_IN_DAYS}-day SLA Miss % (avg execution time)'
        long_timeframe_col_name = f'{LONG_TIMEFRAME_IN_DAYS}-day SLA Miss % (avg execution time)'

        dag_sla_miss_pct_detailed[short_timeframe_col_name] = (
            dag_sla_miss_pct_detailed["sla_miss_percent_one_day"].apply(str) + "% (" +
            dag_sla_miss_pct_detailed["duration"].apply(str) + "s)")

        dag_sla_miss_pct_detailed[medium_timeframe_col_name] = (
            dag_sla_miss_pct_detailed["sla_miss_percent_three_day"].apply(str) + "% (" +
            dag_sla_miss_pct_detailed["duration_y"].apply(str) + "s)")

        dag_sla_miss_pct_detailed[long_timeframe_col_name] = (
            dag_sla_miss_pct_detailed["sla_miss_percent_week"].apply(str) + "% (" +
            dag_sla_miss_pct_detailed["duration_x"].apply(str) + "s)")

        dag_sla_miss_pct_filtered = dag_sla_miss_pct_detailed.filter(
            [
                "Dag: Task",
                "sla",
                short_timeframe_col_name,
                medium_timeframe_col_name,
                long_timeframe_col_name,
            ],
            axis=1,
        ).sort_values(by=[long_timeframe_col_name], ascending=False)

        dag_sla_miss_pct_filtered.rename(columns={"sla": "Current SLA (s)"}, inplace=True)

        dag_sla_miss_pct_recc1 = dag_sla_miss_pct_detailed.nlargest(3, ["sla_miss_percent_week"]).fillna(0)
        dag_sla_miss_pct_recc2 = dag_sla_miss_pct_recc1.filter(
            ["dag_id", "task_id", "sla", "sla_miss_percent_week", "Dag: Task"], axis=1).fillna(0)
        dag_sla_miss_pct_df4_recc3 = pd.merge(
            pd.merge(
                dag_sla_miss_pct_recc2,
                dag_sla_run_count_week_prior_success,
                on=["dag_id", "task_id"],
            ),
            dag_sla_run_count_week_prior_failure,
            on=["dag_id", "task_id"],
            how="left",
        ).fillna(0)
        dag_sla_miss_pct_df4_recc4 = pd.merge(
            pd.merge(
                dag_sla_miss_pct_df4_recc3,
                dag_sla_run_count_week_prior_success_duration_stats,
                on=["dag_id", "task_id"],
                how="left",
            ),
            dag_sla_run_count_week_prior_failure_duration_stats,
            on=["dag_id", "task_id"],
            how="left",
        ).fillna(0)
        dag_sla_miss_pct_df4_recc4["Recommendations"] = (
            dag_sla_miss_pct_df4_recc4["Dag: Task"].apply(str) + " - Of the " +
            dag_sla_miss_pct_df4_recc4["sla_miss_percent_week"].apply(str) +
            "% of the tasks that missed their SLA of " + dag_sla_miss_pct_df4_recc4["sla"].apply(str) + " seconds, " +
            dag_sla_miss_pct_df4_recc4["success_count"].astype(int).apply(str) + " succeeded (min: " +
            dag_sla_miss_pct_df4_recc4["min_x"].round(0).astype(int).apply(str) + "s, avg: " +
            dag_sla_miss_pct_df4_recc4["mean_x"].round(0).astype(int).apply(str) + "s, max: " +
            dag_sla_miss_pct_df4_recc4["max_x"].round(0).astype(int).apply(str) + "s) & " +
            dag_sla_miss_pct_df4_recc4["failure_count"].astype(int).apply(str) + " failed (min: " +
            dag_sla_miss_pct_df4_recc4["min_y"].round(0).astype(int).apply(str) + "s, avg: " +
            dag_sla_miss_pct_df4_recc4["mean_y"].round(0).astype(int).apply(str) + "s, max: " +
            dag_sla_miss_pct_df4_recc4["max_y"].round(0).fillna(0).astype(int).apply(str) + "s)")

        daily_weeklytrend_observations_loop = [
            dag_obs5_sladetailed_oneday,
            dag_obs6_sladetailed_threeday,
            dag_obs7_sladetailed_week,
        ]

        dag_sla_miss_trend = dag_sla_miss_pct_df4_recc4["Recommendations"].tolist()

        return daily_weeklytrend_observations_loop, dag_sla_miss_trend, dag_sla_miss_pct_filtered
    except:
        short_timeframe_col_name = f'{SHORT_TIMEFRAME_IN_DAYS}-Day SLA miss % (avg execution time)'
        medium_timeframe_col_name = f'{MEDIUM_TIMEFRAME_IN_DAYS}-Day SLA miss % (avg execution time)'
        long_timeframe_col_name = f'{LONG_TIMEFRAME_IN_DAYS}-Day SLA miss % (avg execution time)'
        daily_weeklytrend_observations_loop = ""
        dag_sla_miss_trend = ""
        dag_sla_miss_pct_filtered = pd.DataFrame(columns=[
            "Dag: Task",
            "Current SLA",
            short_timeframe_col_name,
            medium_timeframe_col_name,
            long_timeframe_col_name,
        ])
        return daily_weeklytrend_observations_loop, dag_sla_miss_trend, dag_sla_miss_pct_filtered

    Generate SLA dag miss table giving us details about the SLA miss % for the given timeframes along with the average execution time and
    reccomendations for weekly observations.

    Args:
        sla_run_detail (dataframe): Base table consiting of details of all the dag runs that happened
        serialized_dags_slas (dataframe): table consisting of all the dag details

    Returns:
        2 lists consisting of sla_daily_miss and sla_dag_miss reccomendations and 1 dataframe consisting of sla_dag_miss reccomendation
    
sla-miss-report/airflow-sla-miss-report.py